summaryrefslogtreecommitdiffstats
path: root/chart2/source/controller/dialogs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /chart2/source/controller/dialogs
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'chart2/source/controller/dialogs')
-rw-r--r--chart2/source/controller/dialogs/ChangingResource.cxx38
-rw-r--r--chart2/source/controller/dialogs/ChartResourceGroupDlgs.cxx131
-rw-r--r--chart2/source/controller/dialogs/ChartResourceGroups.cxx383
-rw-r--r--chart2/source/controller/dialogs/ChartTypeDialogController.cxx1254
-rw-r--r--chart2/source/controller/dialogs/DataBrowser.cxx1376
-rw-r--r--chart2/source/controller/dialogs/DataBrowser.hxx187
-rw-r--r--chart2/source/controller/dialogs/DataBrowserModel.cxx935
-rw-r--r--chart2/source/controller/dialogs/DataBrowserModel.hxx170
-rw-r--r--chart2/source/controller/dialogs/DialogModel.cxx849
-rw-r--r--chart2/source/controller/dialogs/DialogModel.hxx176
-rw-r--r--chart2/source/controller/dialogs/ObjectNameProvider.cxx868
-rw-r--r--chart2/source/controller/dialogs/RangeSelectionHelper.cxx178
-rw-r--r--chart2/source/controller/dialogs/RangeSelectionListener.cxx61
-rw-r--r--chart2/source/controller/dialogs/TextDirectionListBox.cxx36
-rw-r--r--chart2/source/controller/dialogs/TimerTriggeredControllerLock.cxx52
-rw-r--r--chart2/source/controller/dialogs/TitleDialogData.cxx113
-rw-r--r--chart2/source/controller/dialogs/dlg_ChartType.cxx46
-rw-r--r--chart2/source/controller/dialogs/dlg_ChartType_UNO.cxx113
-rw-r--r--chart2/source/controller/dialogs/dlg_CreationWizard.cxx202
-rw-r--r--chart2/source/controller/dialogs/dlg_CreationWizard_UNO.cxx362
-rw-r--r--chart2/source/controller/dialogs/dlg_DataEditor.cxx148
-rw-r--r--chart2/source/controller/dialogs/dlg_DataSource.cxx178
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertAxis_Grid.cxx88
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertDataLabel.cxx43
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertDataTable.cxx61
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertErrorBars.cxx103
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertLegend.cxx45
-rw-r--r--chart2/source/controller/dialogs/dlg_InsertTitle.cxx41
-rw-r--r--chart2/source/controller/dialogs/dlg_NumberFormat.cxx57
-rw-r--r--chart2/source/controller/dialogs/dlg_NumberFormat.hxx45
-rw-r--r--chart2/source/controller/dialogs/dlg_ObjectProperties.cxx638
-rw-r--r--chart2/source/controller/dialogs/dlg_ShapeFont.cxx61
-rw-r--r--chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx64
-rw-r--r--chart2/source/controller/dialogs/dlg_View3D.cxx81
-rw-r--r--chart2/source/controller/dialogs/res_BarGeometry.cxx65
-rw-r--r--chart2/source/controller/dialogs/res_DataLabel.cxx388
-rw-r--r--chart2/source/controller/dialogs/res_DataLabel.hxx101
-rw-r--r--chart2/source/controller/dialogs/res_DataTableProperties.cxx111
-rw-r--r--chart2/source/controller/dialogs/res_ErrorBar.cxx716
-rw-r--r--chart2/source/controller/dialogs/res_LegendPosition.cxx244
-rw-r--r--chart2/source/controller/dialogs/res_Titles.cxx132
-rw-r--r--chart2/source/controller/dialogs/res_Trendline.cxx434
-rw-r--r--chart2/source/controller/dialogs/res_Trendline.hxx98
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneAppearance.cxx318
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneAppearance.hxx69
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneGeometry.cxx258
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx87
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneIllumination.cxx533
-rw-r--r--chart2/source/controller/dialogs/tp_3D_SceneIllumination.hxx98
-rw-r--r--chart2/source/controller/dialogs/tp_AxisLabel.cxx300
-rw-r--r--chart2/source/controller/dialogs/tp_AxisLabel.hxx83
-rw-r--r--chart2/source/controller/dialogs/tp_AxisPositions.cxx320
-rw-r--r--chart2/source/controller/dialogs/tp_AxisPositions.hxx83
-rw-r--r--chart2/source/controller/dialogs/tp_ChartType.cxx385
-rw-r--r--chart2/source/controller/dialogs/tp_ChartType.hxx94
-rw-r--r--chart2/source/controller/dialogs/tp_DataLabel.cxx54
-rw-r--r--chart2/source/controller/dialogs/tp_DataLabel.hxx48
-rw-r--r--chart2/source/controller/dialogs/tp_DataPointOption.cxx66
-rw-r--r--chart2/source/controller/dialogs/tp_DataPointOption.hxx48
-rw-r--r--chart2/source/controller/dialogs/tp_DataSource.cxx924
-rw-r--r--chart2/source/controller/dialogs/tp_DataSource.hxx149
-rw-r--r--chart2/source/controller/dialogs/tp_DataTable.cxx43
-rw-r--r--chart2/source/controller/dialogs/tp_DataTable.hxx37
-rw-r--r--chart2/source/controller/dialogs/tp_ErrorBars.cxx67
-rw-r--r--chart2/source/controller/dialogs/tp_ErrorBars.hxx50
-rw-r--r--chart2/source/controller/dialogs/tp_LegendPosition.cxx76
-rw-r--r--chart2/source/controller/dialogs/tp_LegendPosition.hxx49
-rw-r--r--chart2/source/controller/dialogs/tp_PointGeometry.cxx78
-rw-r--r--chart2/source/controller/dialogs/tp_PointGeometry.hxx44
-rw-r--r--chart2/source/controller/dialogs/tp_PolarOptions.cxx106
-rw-r--r--chart2/source/controller/dialogs/tp_PolarOptions.hxx57
-rw-r--r--chart2/source/controller/dialogs/tp_RangeChooser.cxx380
-rw-r--r--chart2/source/controller/dialogs/tp_RangeChooser.hxx98
-rw-r--r--chart2/source/controller/dialogs/tp_Scale.cxx637
-rw-r--r--chart2/source/controller/dialogs/tp_Scale.hxx109
-rw-r--r--chart2/source/controller/dialogs/tp_SeriesToAxis.cxx248
-rw-r--r--chart2/source/controller/dialogs/tp_SeriesToAxis.hxx77
-rw-r--r--chart2/source/controller/dialogs/tp_TitleRotation.cxx121
-rw-r--r--chart2/source/controller/dialogs/tp_TitleRotation.hxx61
-rw-r--r--chart2/source/controller/dialogs/tp_Trendline.cxx59
-rw-r--r--chart2/source/controller/dialogs/tp_Trendline.hxx46
-rw-r--r--chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx160
-rw-r--r--chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx72
83 files changed, 18064 insertions, 0 deletions
diff --git a/chart2/source/controller/dialogs/ChangingResource.cxx b/chart2/source/controller/dialogs/ChangingResource.cxx
new file mode 100644
index 0000000000..4cbbe569cc
--- /dev/null
+++ b/chart2/source/controller/dialogs/ChangingResource.cxx
@@ -0,0 +1,38 @@
+/* -*- 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 .
+ */
+
+#include <ChangingResource.hxx>
+
+namespace chart
+{
+ResourceChangeListener::~ResourceChangeListener() {}
+
+ChangingResource::ChangingResource()
+ : m_pChangeListener(nullptr)
+{
+}
+ChangingResource::~ChangingResource() {}
+void ChangingResource::setChangeListener(ResourceChangeListener* pListener)
+{
+ m_pChangeListener = pListener;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/ChartResourceGroupDlgs.cxx b/chart2/source/controller/dialogs/ChartResourceGroupDlgs.cxx
new file mode 100644
index 0000000000..91307afaad
--- /dev/null
+++ b/chart2/source/controller/dialogs/ChartResourceGroupDlgs.cxx
@@ -0,0 +1,131 @@
+/* -*- 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 .
+ */
+
+#include <ChartResourceGroupDlgs.hxx>
+#include <ChartTypeDialogController.hxx>
+
+#include <strings.hrc>
+#include <ResId.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+const sal_uInt16 CUBIC_SPLINE_POS = 0;
+const sal_uInt16 B_SPLINE_POS = 1;
+
+SplinePropertiesDialog::SplinePropertiesDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "modules/schart/ui/smoothlinesdlg.ui", "SmoothLinesDialog")
+ , m_xLB_Spline_Type(m_xBuilder->weld_combo_box("SplineTypeComboBox"))
+ , m_xMF_SplineResolution(m_xBuilder->weld_spin_button("ResolutionSpinbutton"))
+ , m_xFT_SplineOrder(m_xBuilder->weld_label("PolynomialsLabel"))
+ , m_xMF_SplineOrder(m_xBuilder->weld_spin_button("PolynomialsSpinButton"))
+{
+ m_xDialog->set_title(SchResId(STR_DLG_SMOOTH_LINE_PROPERTIES));
+
+ m_xLB_Spline_Type->connect_changed(LINK(this, SplinePropertiesDialog, SplineTypeListBoxHdl));
+}
+
+void SplinePropertiesDialog::fillControls(const ChartTypeParameter& rParameter)
+{
+ switch (rParameter.eCurveStyle)
+ {
+ case CurveStyle_CUBIC_SPLINES:
+ m_xLB_Spline_Type->set_active(CUBIC_SPLINE_POS);
+ break;
+ case CurveStyle_B_SPLINES:
+ m_xLB_Spline_Type->set_active(B_SPLINE_POS);
+ break;
+ default:
+ m_xLB_Spline_Type->set_active(CUBIC_SPLINE_POS);
+ break;
+ }
+ m_xMF_SplineOrder->set_value(rParameter.nSplineOrder);
+ m_xMF_SplineResolution->set_value(rParameter.nCurveResolution);
+
+ //dis/enabling
+ m_xFT_SplineOrder->set_sensitive(m_xLB_Spline_Type->get_active() == B_SPLINE_POS);
+ m_xMF_SplineOrder->set_sensitive(m_xLB_Spline_Type->get_active() == B_SPLINE_POS);
+}
+
+void SplinePropertiesDialog::fillParameter(ChartTypeParameter& rParameter, bool bSmoothLines)
+{
+ if (!bSmoothLines)
+ rParameter.eCurveStyle = CurveStyle_LINES;
+ else if (m_xLB_Spline_Type->get_active() == CUBIC_SPLINE_POS)
+ rParameter.eCurveStyle = CurveStyle_CUBIC_SPLINES;
+ else if (m_xLB_Spline_Type->get_active() == B_SPLINE_POS)
+ rParameter.eCurveStyle = CurveStyle_B_SPLINES;
+
+ rParameter.nCurveResolution = m_xMF_SplineResolution->get_value();
+ rParameter.nSplineOrder = m_xMF_SplineOrder->get_value();
+}
+
+IMPL_LINK_NOARG(SplinePropertiesDialog, SplineTypeListBoxHdl, weld::ComboBox&, void)
+{
+ m_xFT_SplineOrder->set_sensitive(m_xLB_Spline_Type->get_active() == B_SPLINE_POS);
+ m_xMF_SplineOrder->set_sensitive(m_xLB_Spline_Type->get_active() == B_SPLINE_POS);
+}
+
+SteppedPropertiesDialog::SteppedPropertiesDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "modules/schart/ui/steppedlinesdlg.ui", "SteppedLinesDialog")
+ , m_xRB_Start(m_xBuilder->weld_radio_button("step_start_rb"))
+ , m_xRB_End(m_xBuilder->weld_radio_button("step_end_rb"))
+ , m_xRB_CenterX(m_xBuilder->weld_radio_button("step_center_x_rb"))
+ , m_xRB_CenterY(m_xBuilder->weld_radio_button("step_center_y_rb"))
+{
+ m_xDialog->set_title(SchResId(STR_DLG_STEPPED_LINE_PROPERTIES));
+}
+
+void SteppedPropertiesDialog::fillControls(const ChartTypeParameter& rParameter)
+{
+ switch (rParameter.eCurveStyle)
+ {
+ case CurveStyle_STEP_END:
+ m_xRB_End->set_active(true);
+ break;
+ case CurveStyle_STEP_CENTER_X:
+ m_xRB_CenterX->set_active(true);
+ break;
+ case CurveStyle_STEP_CENTER_Y:
+ m_xRB_CenterY->set_active(true);
+ break;
+ default: // includes CurveStyle_STEP_START
+ m_xRB_Start->set_active(true);
+ break;
+ }
+}
+void SteppedPropertiesDialog::fillParameter(ChartTypeParameter& rParameter, bool bSteppedLines)
+{
+ if (!bSteppedLines)
+ rParameter.eCurveStyle = CurveStyle_LINES;
+ else if (m_xRB_CenterY->get_active())
+ rParameter.eCurveStyle = CurveStyle_STEP_CENTER_Y;
+ else if (m_xRB_Start->get_active())
+ rParameter.eCurveStyle = CurveStyle_STEP_START;
+ else if (m_xRB_End->get_active())
+ rParameter.eCurveStyle = CurveStyle_STEP_END;
+ else if (m_xRB_CenterX->get_active())
+ rParameter.eCurveStyle = CurveStyle_STEP_CENTER_X;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/ChartResourceGroups.cxx b/chart2/source/controller/dialogs/ChartResourceGroups.cxx
new file mode 100644
index 0000000000..e1550d2766
--- /dev/null
+++ b/chart2/source/controller/dialogs/ChartResourceGroups.cxx
@@ -0,0 +1,383 @@
+/* -*- 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 .
+ */
+
+#include <ChartResourceGroups.hxx>
+#include <ChartResourceGroupDlgs.hxx>
+
+#include <strings.hrc>
+#include <ResId.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+Dim3DLookResourceGroup::Dim3DLookResourceGroup(weld::Builder* pBuilder)
+ : m_xCB_3DLook(pBuilder->weld_check_button("3dlook"))
+ , m_xLB_Scheme(pBuilder->weld_combo_box("3dscheme"))
+{
+ m_xCB_3DLook->connect_toggled(LINK(this, Dim3DLookResourceGroup, Dim3DLookCheckHdl));
+ m_xLB_Scheme->connect_changed(LINK(this, Dim3DLookResourceGroup, SelectSchemeHdl));
+}
+
+void Dim3DLookResourceGroup::showControls(bool bShow)
+{
+ m_xCB_3DLook->set_visible(bShow);
+ m_xLB_Scheme->set_visible(bShow);
+}
+
+void Dim3DLookResourceGroup::fillControls(const ChartTypeParameter& rParameter)
+{
+ m_xCB_3DLook->set_active(rParameter.b3DLook);
+ m_xLB_Scheme->set_sensitive(rParameter.b3DLook);
+
+ // tdf#124295 - select always a 3D scheme
+ switch (rParameter.eThreeDLookScheme)
+ {
+ case ThreeDLookScheme::ThreeDLookScheme_Simple:
+ m_xLB_Scheme->set_active(POS_3DSCHEME_SIMPLE);
+ break;
+ case ThreeDLookScheme::ThreeDLookScheme_Realistic:
+ case ThreeDLookScheme::ThreeDLookScheme_Unknown:
+ m_xLB_Scheme->set_active(POS_3DSCHEME_REALISTIC);
+ break;
+ }
+}
+
+void Dim3DLookResourceGroup::fillParameter(ChartTypeParameter& rParameter)
+{
+ rParameter.b3DLook = m_xCB_3DLook->get_active();
+ // tdf#124295 - select always a 3D scheme
+ switch (m_xLB_Scheme->get_active())
+ {
+ case POS_3DSCHEME_SIMPLE:
+ rParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Simple;
+ break;
+ default:
+ rParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Realistic;
+ }
+}
+
+IMPL_LINK_NOARG(Dim3DLookResourceGroup, Dim3DLookCheckHdl, weld::Toggleable&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+IMPL_LINK_NOARG(Dim3DLookResourceGroup, SelectSchemeHdl, weld::ComboBox&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+SortByXValuesResourceGroup::SortByXValuesResourceGroup(weld::Builder* pBuilder)
+ : m_xCB_XValueSorting(pBuilder->weld_check_button("sort"))
+{
+ m_xCB_XValueSorting->connect_toggled(
+ LINK(this, SortByXValuesResourceGroup, SortByXValuesCheckHdl));
+}
+
+void SortByXValuesResourceGroup::showControls(bool bShow)
+{
+ m_xCB_XValueSorting->set_visible(bShow);
+}
+
+void SortByXValuesResourceGroup::fillControls(const ChartTypeParameter& rParameter)
+{
+ m_xCB_XValueSorting->set_active(rParameter.bSortByXValues);
+}
+
+void SortByXValuesResourceGroup::fillParameter(ChartTypeParameter& rParameter)
+{
+ rParameter.bSortByXValues = m_xCB_XValueSorting->get_active();
+}
+
+IMPL_LINK_NOARG(SortByXValuesResourceGroup, SortByXValuesCheckHdl, weld::Toggleable&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+StackingResourceGroup::StackingResourceGroup(weld::Builder* pBuilder)
+ : m_xCB_Stacked(pBuilder->weld_check_button("stack"))
+ , m_xRB_Stack_Y(pBuilder->weld_radio_button("ontop"))
+ , m_xRB_Stack_Y_Percent(pBuilder->weld_radio_button("percent"))
+ , m_xRB_Stack_Z(pBuilder->weld_radio_button("deep"))
+{
+ m_xCB_Stacked->connect_toggled(LINK(this, StackingResourceGroup, StackingEnableHdl));
+ m_xRB_Stack_Y->connect_toggled(LINK(this, StackingResourceGroup, StackingChangeHdl));
+ m_xRB_Stack_Y_Percent->connect_toggled(LINK(this, StackingResourceGroup, StackingChangeHdl));
+ m_xRB_Stack_Z->connect_toggled(LINK(this, StackingResourceGroup, StackingChangeHdl));
+}
+
+void StackingResourceGroup::showControls(bool bShow)
+{
+ m_xCB_Stacked->set_visible(bShow);
+ m_xRB_Stack_Y->set_visible(bShow);
+ m_xRB_Stack_Y_Percent->set_visible(bShow);
+ m_xRB_Stack_Z->set_visible(false);
+}
+
+void StackingResourceGroup::fillControls(const ChartTypeParameter& rParameter)
+{
+ m_xCB_Stacked->set_active(
+ rParameter.eStackMode != GlobalStackMode_NONE
+ && rParameter.eStackMode
+ != GlobalStackMode_STACK_Z); //todo remove this condition if z stacking radio button is really used
+ switch (rParameter.eStackMode)
+ {
+ case GlobalStackMode_STACK_Y:
+ m_xRB_Stack_Y->set_active(true);
+ break;
+ case GlobalStackMode_STACK_Y_PERCENT:
+ m_xRB_Stack_Y_Percent->set_active(true);
+ break;
+ case GlobalStackMode_STACK_Z:
+ //todo uncomment this condition if z stacking radio button is really used
+ /*
+ if( rParameter.b3DLook )
+ m_xRB_Stack_Z->set_active(true);
+ else
+ */
+ m_xRB_Stack_Y->set_active(true);
+ break;
+ default:
+ m_xRB_Stack_Y->set_active(true);
+ break;
+ }
+ //dis/enabling
+ m_xCB_Stacked->set_sensitive(!rParameter.bXAxisWithValues);
+ m_xRB_Stack_Y->set_sensitive(m_xCB_Stacked->get_active() && !rParameter.bXAxisWithValues);
+ m_xRB_Stack_Y_Percent->set_sensitive(m_xCB_Stacked->get_active()
+ && !rParameter.bXAxisWithValues);
+ m_xRB_Stack_Z->set_sensitive(m_xCB_Stacked->get_active() && rParameter.b3DLook);
+}
+
+void StackingResourceGroup::fillParameter(ChartTypeParameter& rParameter)
+{
+ if (!m_xCB_Stacked->get_active())
+ rParameter.eStackMode = GlobalStackMode_NONE;
+ else if (m_xRB_Stack_Y->get_active())
+ rParameter.eStackMode = GlobalStackMode_STACK_Y;
+ else if (m_xRB_Stack_Y_Percent->get_active())
+ rParameter.eStackMode = GlobalStackMode_STACK_Y_PERCENT;
+ else if (m_xRB_Stack_Z->get_active())
+ rParameter.eStackMode = GlobalStackMode_STACK_Z;
+}
+
+IMPL_LINK(StackingResourceGroup, StackingChangeHdl, weld::Toggleable&, rRadio, void)
+{
+ //for each radio click there are coming two change events
+ //first uncheck of previous button -> ignore that call
+ //the second call gives the check of the new button
+ if (m_pChangeListener && rRadio.get_active())
+ m_pChangeListener->stateChanged();
+}
+
+IMPL_LINK_NOARG(StackingResourceGroup, StackingEnableHdl, weld::Toggleable&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+SplineResourceGroup::SplineResourceGroup(weld::Builder* pBuilder, weld::Window* pParent)
+ : m_pParent(pParent)
+ , m_xFT_LineType(pBuilder->weld_label("linetypeft"))
+ , m_xLB_LineType(pBuilder->weld_combo_box("linetype"))
+ , m_xPB_DetailsDialog(pBuilder->weld_button("properties"))
+{
+ m_xLB_LineType->connect_changed(LINK(this, SplineResourceGroup, LineTypeChangeHdl));
+}
+
+std::shared_ptr<SplinePropertiesDialog> SplineResourceGroup::getSplinePropertiesDialog()
+{
+ if (!m_xSplinePropertiesDialog)
+ {
+ m_xSplinePropertiesDialog.reset(new SplinePropertiesDialog(m_pParent));
+ }
+ return m_xSplinePropertiesDialog;
+}
+
+std::shared_ptr<SteppedPropertiesDialog> SplineResourceGroup::getSteppedPropertiesDialog()
+{
+ if (!m_xSteppedPropertiesDialog)
+ {
+ m_xSteppedPropertiesDialog.reset(new SteppedPropertiesDialog(m_pParent));
+ }
+ return m_xSteppedPropertiesDialog;
+}
+
+void SplineResourceGroup::showControls(bool bShow)
+{
+ m_xFT_LineType->set_visible(bShow);
+ m_xLB_LineType->set_visible(bShow);
+ m_xPB_DetailsDialog->set_visible(bShow);
+}
+
+void SplineResourceGroup::fillControls(const ChartTypeParameter& rParameter)
+{
+ switch (rParameter.eCurveStyle)
+ {
+ case CurveStyle_LINES:
+ m_xLB_LineType->set_active(POS_LINETYPE_STRAIGHT);
+ m_xPB_DetailsDialog->set_sensitive(false);
+ break;
+ case CurveStyle_CUBIC_SPLINES:
+ case CurveStyle_B_SPLINES:
+ m_xLB_LineType->set_active(POS_LINETYPE_SMOOTH);
+ m_xPB_DetailsDialog->set_sensitive(true);
+ m_xPB_DetailsDialog->connect_clicked(
+ LINK(this, SplineResourceGroup, SplineDetailsDialogHdl));
+ m_xPB_DetailsDialog->set_tooltip_text(SchResId(STR_DLG_SMOOTH_LINE_PROPERTIES));
+ getSplinePropertiesDialog()->fillControls(rParameter);
+ break;
+ case CurveStyle_STEP_START:
+ case CurveStyle_STEP_END:
+ case CurveStyle_STEP_CENTER_X:
+ case CurveStyle_STEP_CENTER_Y:
+ m_xLB_LineType->set_active(POS_LINETYPE_STEPPED);
+ m_xPB_DetailsDialog->set_sensitive(true);
+ m_xPB_DetailsDialog->connect_clicked(
+ LINK(this, SplineResourceGroup, SteppedDetailsDialogHdl));
+ m_xPB_DetailsDialog->set_tooltip_text(SchResId(STR_DLG_STEPPED_LINE_PROPERTIES));
+ getSteppedPropertiesDialog()->fillControls(rParameter);
+ break;
+ default:
+ m_xLB_LineType->set_active(-1);
+ m_xPB_DetailsDialog->set_sensitive(false);
+ }
+}
+void SplineResourceGroup::fillParameter(ChartTypeParameter& rParameter)
+{
+ switch (m_xLB_LineType->get_active())
+ {
+ case POS_LINETYPE_SMOOTH:
+ getSplinePropertiesDialog()->fillParameter(rParameter, true);
+ break;
+ case POS_LINETYPE_STEPPED:
+ getSteppedPropertiesDialog()->fillParameter(rParameter, true);
+ break;
+ default: // includes POS_LINETYPE_STRAIGHT
+ rParameter.eCurveStyle = CurveStyle_LINES;
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SplineResourceGroup, LineTypeChangeHdl, weld::ComboBox&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+IMPL_LINK_NOARG(SplineResourceGroup, SplineDetailsDialogHdl, weld::Button&, void)
+{
+ ChartTypeParameter aOldParameter;
+ std::shared_ptr<SplinePropertiesDialog> xDlg = getSplinePropertiesDialog();
+ xDlg->fillParameter(aOldParameter, m_xLB_LineType->get_active() == POS_LINETYPE_SMOOTH);
+
+ const sal_Int32 iOldLineTypePos = m_xLB_LineType->get_active();
+ m_xLB_LineType->set_active(POS_LINETYPE_SMOOTH);
+ weld::GenericDialogController::runAsync(xDlg, [this, xDlg, aOldParameter,
+ iOldLineTypePos](sal_Int32 nResult) {
+ m_xSplinePropertiesDialog = nullptr;
+ auto xNewDlg = getSplinePropertiesDialog();
+
+ if (nResult == RET_OK)
+ {
+ ChartTypeParameter aNewParameter;
+ xDlg->fillParameter(aNewParameter, m_xLB_LineType->get_active() == POS_LINETYPE_SMOOTH);
+ xNewDlg->fillControls(aNewParameter);
+
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+ }
+ else
+ {
+ //restore old state:
+ m_xLB_LineType->set_active(iOldLineTypePos);
+ xNewDlg->fillControls(aOldParameter);
+ }
+ });
+}
+
+IMPL_LINK_NOARG(SplineResourceGroup, SteppedDetailsDialogHdl, weld::Button&, void)
+{
+ ChartTypeParameter aOldParameter;
+ std::shared_ptr<SteppedPropertiesDialog> xDlg = getSteppedPropertiesDialog();
+ xDlg->fillParameter(aOldParameter, m_xLB_LineType->get_active() == POS_LINETYPE_STEPPED);
+
+ const sal_Int32 iOldLineTypePos = m_xLB_LineType->get_active();
+ m_xLB_LineType->set_active(POS_LINETYPE_STEPPED);
+
+ weld::GenericDialogController::runAsync(
+ xDlg, [this, xDlg, aOldParameter, iOldLineTypePos](sal_Int32 nResult) {
+ m_xSteppedPropertiesDialog = nullptr;
+ auto xNewDlg = getSteppedPropertiesDialog();
+
+ if (nResult == RET_OK)
+ {
+ ChartTypeParameter aNewParameter;
+ xDlg->fillParameter(aNewParameter,
+ m_xLB_LineType->get_active() == POS_LINETYPE_STEPPED);
+ xNewDlg->fillControls(aNewParameter);
+
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+ }
+ else
+ {
+ //restore old state:
+ m_xLB_LineType->set_active(iOldLineTypePos);
+ xDlg->fillControls(aOldParameter);
+ }
+ });
+}
+
+GeometryResourceGroup::GeometryResourceGroup(weld::Builder* pBuilder)
+ : m_aGeometryResources(pBuilder)
+{
+ m_aGeometryResources.connect_changed(LINK(this, GeometryResourceGroup, GeometryChangeHdl));
+}
+
+void GeometryResourceGroup::showControls(bool bShow) { m_aGeometryResources.set_visible(bShow); }
+
+void GeometryResourceGroup::fillControls(const ChartTypeParameter& rParameter)
+{
+ sal_uInt16 nGeometry3D = static_cast<sal_uInt16>(rParameter.nGeometry3D);
+ m_aGeometryResources.select(nGeometry3D);
+ m_aGeometryResources.set_sensitive(rParameter.b3DLook);
+}
+
+void GeometryResourceGroup::fillParameter(ChartTypeParameter& rParameter)
+{
+ rParameter.nGeometry3D = 1;
+ int nSelected = m_aGeometryResources.get_selected_index();
+ if (nSelected != -1)
+ rParameter.nGeometry3D = nSelected;
+}
+
+IMPL_LINK_NOARG(GeometryResourceGroup, GeometryChangeHdl, weld::TreeView&, void)
+{
+ if (m_pChangeListener)
+ m_pChangeListener->stateChanged();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx
new file mode 100644
index 0000000000..b52dbc2897
--- /dev/null
+++ b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx
@@ -0,0 +1,1254 @@
+/* -*- 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 .
+ */
+
+#include <ChartTypeDialogController.hxx>
+#include <ChartTypeManager.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <ResId.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <ChartModelHelper.hxx>
+#include <DataSeries.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <ControllerLockGuard.hxx>
+#include <AxisHelper.hxx>
+#include <unonames.hxx>
+#include <BaseCoordinateSystem.hxx>
+#include <ChartModel.hxx>
+
+#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
+
+#include <svtools/valueset.hxx>
+#include <vcl/image.hxx>
+#include <vcl/settings.hxx>
+
+#include <comphelper/diagnose_ex.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+ChartTypeParameter::ChartTypeParameter()
+ : nSubTypeIndex( 1 )
+ , bXAxisWithValues( false )
+ , b3DLook( false )
+ , bSymbols( true )
+ , bLines( true )
+ , eStackMode( GlobalStackMode_NONE )
+ , eCurveStyle( CurveStyle_LINES )
+ , nCurveResolution(20)
+ , nSplineOrder(3)
+ , nGeometry3D(DataPointGeometry3D::CUBOID)
+ , eThreeDLookScheme(ThreeDLookScheme::ThreeDLookScheme_Realistic)
+ , bSortByXValues(false)
+ , mbRoundedEdge(false)
+{
+}
+
+ChartTypeParameter::ChartTypeParameter( sal_Int32 SubTypeIndex, bool HasXAxisWithValues
+ , bool Is3DLook, GlobalStackMode nStackMode
+ , bool HasSymbols, bool HasLines
+ , CurveStyle nCurveStyle )
+ : nSubTypeIndex( SubTypeIndex )
+ , bXAxisWithValues( HasXAxisWithValues )
+ , b3DLook( Is3DLook )
+ , bSymbols( HasSymbols )
+ , bLines( HasLines )
+ , eStackMode( nStackMode )
+ , eCurveStyle( nCurveStyle )
+ , nCurveResolution(20)
+ , nSplineOrder(3)
+ , nGeometry3D(DataPointGeometry3D::CUBOID)
+ , eThreeDLookScheme(ThreeDLookScheme::ThreeDLookScheme_Realistic)
+ , bSortByXValues(false)
+ , mbRoundedEdge(false)
+{
+}
+
+bool ChartTypeParameter::mapsToSameService( const ChartTypeParameter& rParameter ) const
+{
+ return mapsToSimilarService( rParameter, 0 );
+}
+bool ChartTypeParameter::mapsToSimilarService( const ChartTypeParameter& rParameter, sal_Int32 nTheHigherTheLess ) const
+{
+ sal_Int32 nMax=7;
+ if(nTheHigherTheLess>nMax)
+ return true;
+ if( bXAxisWithValues!=rParameter.bXAxisWithValues )
+ return nTheHigherTheLess>nMax-1;
+ if( b3DLook!=rParameter.b3DLook )
+ return nTheHigherTheLess>nMax-2;
+ if( eStackMode!=rParameter.eStackMode )
+ return nTheHigherTheLess>nMax-3;
+ if( nSubTypeIndex!=rParameter.nSubTypeIndex )
+ return nTheHigherTheLess>nMax-4;
+ if( bSymbols!=rParameter.bSymbols )
+ return nTheHigherTheLess>nMax-5;
+ if( bLines!=rParameter.bLines )
+ return nTheHigherTheLess>nMax-6;
+ return true;
+}
+
+ChartTypeDialogController::ChartTypeDialogController()
+ : bSupportsXAxisWithValues(false)
+ , bSupports3D(true)
+{
+}
+
+ChartTypeDialogController::~ChartTypeDialogController()
+{
+}
+
+bool ChartTypeDialogController::isSubType( const OUString& rServiceName )
+{
+ const tTemplateServiceChartTypeParameterMap& rTemplateMap = getTemplateMap();
+ tTemplateServiceChartTypeParameterMap::const_iterator aIt( rTemplateMap.find( rServiceName ));
+ return aIt != rTemplateMap.end();
+}
+ChartTypeParameter ChartTypeDialogController::getChartTypeParameterForService(
+ const OUString& rServiceName
+ , const uno::Reference< beans::XPropertySet >& xTemplateProps )
+{
+ ChartTypeParameter aRet;
+ const tTemplateServiceChartTypeParameterMap& rTemplateMap = getTemplateMap();
+ tTemplateServiceChartTypeParameterMap::const_iterator aIt( rTemplateMap.find( rServiceName ));
+ if( aIt != rTemplateMap.end())
+ aRet = (*aIt).second;
+ if( xTemplateProps.is() )
+ {
+ try
+ {
+ xTemplateProps->getPropertyValue( CHART_UNONAME_CURVE_STYLE ) >>= aRet.eCurveStyle;
+ xTemplateProps->getPropertyValue( CHART_UNONAME_CURVE_RESOLUTION ) >>= aRet.nCurveResolution;
+ xTemplateProps->getPropertyValue( CHART_UNONAME_SPLINE_ORDER ) >>= aRet.nSplineOrder;
+ }
+ catch( uno::Exception & ex )
+ {
+ //not all templates need to support CurveStyle, CurveResolution or SplineOrder
+ ex.Context.is();//to have debug information without compilation warnings
+ }
+
+ try
+ {
+ xTemplateProps->getPropertyValue( "Geometry3D" ) >>= aRet.nGeometry3D;
+ }
+ catch( uno::Exception& ex )
+ {
+ //not all templates need to support Geometry3D
+ ex.Context.is();//to have debug information without compilation warnings
+ }
+ }
+ return aRet;
+}
+void ChartTypeDialogController::adjustSubTypeAndEnableControls( ChartTypeParameter& /*rParameter*/ )
+{
+}
+void ChartTypeDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.eStackMode=GlobalStackMode_STACK_Y;
+ break;
+ case 3:
+ rParameter.eStackMode=GlobalStackMode_STACK_Y_PERCENT;
+ break;
+ case 4:
+ rParameter.eStackMode=GlobalStackMode_STACK_Z;
+ break;
+ default:
+ rParameter.eStackMode=GlobalStackMode_NONE;
+ break;
+ }
+}
+void ChartTypeDialogController::adjustParameterToMainType( ChartTypeParameter& rParameter )
+{
+ bool bFoundSomeMatch=false;
+
+ rParameter.bXAxisWithValues = bSupportsXAxisWithValues;
+ if( rParameter.b3DLook && !bSupports3D )
+ rParameter.b3DLook = false;
+ if(!rParameter.b3DLook && rParameter.eStackMode==GlobalStackMode_STACK_Z)
+ rParameter.eStackMode = GlobalStackMode_NONE;
+
+ const tTemplateServiceChartTypeParameterMap& rMap = getTemplateMap();
+ for( sal_Int32 nMatchPrecision=0; nMatchPrecision<7 && !bFoundSomeMatch; nMatchPrecision++ )
+ {
+ for (auto const& elem : rMap)
+ {
+ if( rParameter.mapsToSimilarService( elem.second, nMatchPrecision ) )
+ {
+ //remind some values
+ ThreeDLookScheme aScheme = rParameter.eThreeDLookScheme;
+ sal_Int32 nCurveResolution = rParameter.nCurveResolution;
+ sal_Int32 nSplineOrder = rParameter.nSplineOrder;
+ CurveStyle eCurveStyle = rParameter.eCurveStyle;
+ sal_Int32 nGeometry3D = rParameter.nGeometry3D;
+ bool bSortByXValues = rParameter.bSortByXValues;
+ bool bRoundedEdge = rParameter.mbRoundedEdge;
+
+ rParameter = elem.second;
+
+ //some values should not be changed with charttype
+ rParameter.eThreeDLookScheme = aScheme;
+ rParameter.nCurveResolution = nCurveResolution;
+ rParameter.nSplineOrder =nSplineOrder;
+ rParameter.eCurveStyle = eCurveStyle;
+ rParameter.nGeometry3D = nGeometry3D;
+ rParameter.bSortByXValues = bSortByXValues;
+ rParameter.mbRoundedEdge = bRoundedEdge;
+
+ bFoundSomeMatch = true;
+ break;
+ }
+ }
+ }
+ if(!bFoundSomeMatch)
+ {
+ if(!rMap.empty())
+ rParameter = (*rMap.begin()).second;
+ else
+ rParameter = ChartTypeParameter();
+ }
+}
+OUString ChartTypeDialogController::getServiceNameForParameter( const ChartTypeParameter& rParameter ) const
+{
+ ChartTypeParameter aParameter(rParameter);
+ if( aParameter.bXAxisWithValues )
+ aParameter.eStackMode = GlobalStackMode_NONE;
+ if(!aParameter.b3DLook && aParameter.eStackMode==GlobalStackMode_STACK_Z)
+ aParameter.eStackMode = GlobalStackMode_NONE;
+ const tTemplateServiceChartTypeParameterMap& rMap = getTemplateMap();
+ for (auto const& elem : rMap)
+ {
+ if( aParameter.mapsToSameService(elem.second) )
+ return elem.first;
+ }
+
+ OSL_FAIL( "ChartType not implemented yet - use fallback to similar type" );
+ for( sal_Int32 nMatchPrecision=1; nMatchPrecision<8; nMatchPrecision++ )
+ {
+ for (auto const& elem : rMap)
+ {
+ if( aParameter.mapsToSimilarService(elem.second, nMatchPrecision) )
+ return elem.first;
+ }
+ }
+ return OUString();
+}
+rtl::Reference< ChartTypeTemplate > ChartTypeDialogController::getCurrentTemplate(
+ const ChartTypeParameter& rParameter
+ , const rtl::Reference< ChartTypeManager >& xTemplateManager ) const
+{
+ rtl::Reference< ChartTypeTemplate > xTemplate;
+
+ OUString aServiceName( getServiceNameForParameter( rParameter ) );
+ if(!aServiceName.isEmpty())
+ {
+ xTemplate = xTemplateManager->createTemplate( aServiceName );
+ if(xTemplate.is())
+ {
+ uno::Reference< beans::XPropertySet > xTemplateProps( static_cast<cppu::OWeakObject*>(xTemplate.get()), uno::UNO_QUERY );
+ if(xTemplateProps.is())
+ {
+ try
+ {
+ xTemplateProps->setPropertyValue( CHART_UNONAME_CURVE_STYLE , uno::Any(rParameter.eCurveStyle) );
+ xTemplateProps->setPropertyValue( CHART_UNONAME_CURVE_RESOLUTION , uno::Any(rParameter.nCurveResolution) );
+ xTemplateProps->setPropertyValue( CHART_UNONAME_SPLINE_ORDER , uno::Any(rParameter.nSplineOrder) );
+ }
+ catch( uno::Exception & ex )
+ {
+ //not all templates need to support CurveStyle, CurveResolution or SplineOrder
+ ex.Context.is();//to have debug information without compilation warnings
+ }
+ try
+ {
+ xTemplateProps->setPropertyValue( "Geometry3D" , uno::Any(rParameter.nGeometry3D) );
+ }
+ catch( uno::Exception & ex )
+ {
+ //not all templates need to support Geometry3D
+ ex.Context.is();//to have debug information without compilation warnings
+ }
+
+ try
+ {
+ setTemplateProperties( xTemplateProps );
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ }
+ }
+ return xTemplate;
+}
+
+void ChartTypeDialogController::commitToModel( const ChartTypeParameter& rParameter
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< ::chart::ChartTypeManager > xTemplateManager = xChartModel->getTypeManager();
+ rtl::Reference< ::chart::ChartTypeTemplate > xTemplate( getCurrentTemplate( rParameter, xTemplateManager ) );
+ if(!xTemplate.is())
+ return;
+
+ // locked controllers
+ ControllerLockGuardUNO aCtrlLockGuard( xChartModel );
+ rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
+ Diagram::tTemplateWithServiceName aTemplateWithService;
+ if (xDiagram)
+ aTemplateWithService = xDiagram->getTemplate( xTemplateManager );
+ if( aTemplateWithService.xChartTypeTemplate.is())
+ aTemplateWithService.xChartTypeTemplate->resetStyles2( xDiagram );
+ xTemplate->changeDiagram( xDiagram );
+ if( AllSettings::GetMathLayoutRTL() )
+ AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
+ if( rParameter.b3DLook )
+ xDiagram->setScheme( rParameter.eThreeDLookScheme );
+
+ if (xDiagram.is())
+ {
+ xDiagram->setPropertyValue(CHART_UNONAME_SORT_BY_XVALUES, uno::Any(rParameter.bSortByXValues));
+ }
+}
+void ChartTypeDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& /*rParameter*/ )
+{
+ rSubTypeList.Clear();
+}
+bool ChartTypeDialogController::shouldShow_3DLookControl() const
+{
+ return false;
+}
+bool ChartTypeDialogController::shouldShow_StackingControl() const
+{
+ return false;
+}
+bool ChartTypeDialogController::shouldShow_SplineControl() const
+{
+ return false;
+}
+bool ChartTypeDialogController::shouldShow_GeometryControl() const
+{
+ return false;
+}
+bool ChartTypeDialogController::shouldShow_SortByXValuesResourceGroup() const
+{
+ return false;
+}
+
+void ChartTypeDialogController::showExtraControls(weld::Builder* /*pBuilder*/)
+{
+}
+void ChartTypeDialogController::hideExtraControls() const
+{
+}
+void ChartTypeDialogController::fillExtraControls( const rtl::Reference<::chart::ChartModel>& /*xChartModel*/
+ , const uno::Reference< beans::XPropertySet >& /*xTemplateProps*/ ) const
+{
+}
+void ChartTypeDialogController::setTemplateProperties( const uno::Reference< beans::XPropertySet >& /*xTemplateProps*/ ) const
+{
+}
+
+ColumnOrBarChartDialogController_Base::ColumnOrBarChartDialogController_Base()
+{
+}
+ColumnOrBarChartDialogController_Base::~ColumnOrBarChartDialogController_Base()
+{
+}
+bool ColumnOrBarChartDialogController_Base::shouldShow_3DLookControl() const
+{
+ return true;
+}
+bool ColumnOrBarChartDialogController_Base::shouldShow_GeometryControl() const
+{
+ return true;
+}
+void ColumnOrBarChartDialogController_Base::adjustSubTypeAndEnableControls( ChartTypeParameter& rParameter )
+{
+ if(rParameter.nSubTypeIndex>3 && !rParameter.b3DLook)
+ {
+ rParameter.nSubTypeIndex=1;
+ }
+}
+ColumnChartDialogController::ColumnChartDialogController()
+{
+}
+ColumnChartDialogController::~ColumnChartDialogController()
+{
+}
+OUString ColumnChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_COLUMN);
+}
+
+OUString ColumnChartDialogController::getImage()
+{
+ return BMP_TYPE_COLUMN;
+}
+
+const tTemplateServiceChartTypeParameterMap& ColumnChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Column" , ChartTypeParameter(1,false,false,GlobalStackMode_NONE)},
+ {"com.sun.star.chart2.template.StackedColumn" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.PercentStackedColumn" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y_PERCENT)},
+ {"com.sun.star.chart2.template.ThreeDColumnFlat" , ChartTypeParameter(1,false,true,GlobalStackMode_NONE)},
+ {"com.sun.star.chart2.template.StackedThreeDColumnFlat" , ChartTypeParameter(2,false,true,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.PercentStackedThreeDColumnFlat" , ChartTypeParameter(3,false,true,GlobalStackMode_STACK_Y_PERCENT)},
+ {"com.sun.star.chart2.template.ThreeDColumnDeep" , ChartTypeParameter(4,false,true,GlobalStackMode_STACK_Z)}};
+ return s_aTemplateMap;
+}
+void ColumnChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ if( rParameter.b3DLook )
+ {
+ switch(rParameter.nGeometry3D)
+ {
+ case DataPointGeometry3D::CYLINDER:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_SAEULE_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_SAEULE_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_SAEULE_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_SAEULE_3D_4));
+ break;
+ case DataPointGeometry3D::CONE:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_KEGEL_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_KEGEL_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_KEGEL_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_KEGEL_3D_4));
+ break;
+ case DataPointGeometry3D::PYRAMID:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_PYRAMID_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_PYRAMID_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_PYRAMID_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_PYRAMID_3D_4));
+ break;
+ default: //DataPointGeometry3D::CUBOID:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_COLUMNS_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_COLUMNS_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_COLUMNS_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_COLUMNS_3D));
+ break;
+ }
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_COLUMNS_2D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_COLUMNS_2D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_COLUMNS_2D_3));
+ }
+
+ rSubTypeList.SetItemText( 1, SchResId( STR_NORMAL ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_STACKED ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_PERCENT ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_DEEP ) );
+}
+
+BarChartDialogController::BarChartDialogController()
+{
+}
+
+BarChartDialogController::~BarChartDialogController()
+{
+}
+
+OUString BarChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_BAR);
+}
+
+OUString BarChartDialogController::getImage()
+{
+ return BMP_TYPE_BAR;
+}
+
+const tTemplateServiceChartTypeParameterMap& BarChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Bar" , ChartTypeParameter(1,false,false,GlobalStackMode_NONE)},
+ {"com.sun.star.chart2.template.StackedBar" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.PercentStackedBar" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y_PERCENT)},
+ {"com.sun.star.chart2.template.ThreeDBarFlat" , ChartTypeParameter(1,false,true,GlobalStackMode_NONE)},
+ {"com.sun.star.chart2.template.StackedThreeDBarFlat" , ChartTypeParameter(2,false,true,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.PercentStackedThreeDBarFlat" , ChartTypeParameter(3,false,true,GlobalStackMode_STACK_Y_PERCENT)},
+ {"com.sun.star.chart2.template.ThreeDBarDeep" , ChartTypeParameter(4,false,true,GlobalStackMode_STACK_Z)}};
+ return s_aTemplateMap;
+}
+void BarChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ if( rParameter.b3DLook )
+ {
+ switch(rParameter.nGeometry3D)
+ {
+ case DataPointGeometry3D::CYLINDER:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_ROEHRE_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_ROEHRE_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_ROEHRE_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_ROEHRE_3D_4));
+ break;
+ case DataPointGeometry3D::CONE:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_KEGELQ_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_KEGELQ_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_KEGELQ_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_KEGELQ_3D_4));
+ break;
+ case DataPointGeometry3D::PYRAMID:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_PYRAMIDQ_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_PYRAMIDQ_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_PYRAMIDQ_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_PYRAMIDQ_3D_4));
+ break;
+ default: //DataPointGeometry3D::CUBOID:
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_BARS_3D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_BARS_3D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_BARS_3D_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_BARS_3D));
+ break;
+ }
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_BARS_2D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_BARS_2D_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_BARS_2D_3));
+ }
+ rSubTypeList.SetItemText( 1, SchResId( STR_NORMAL ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_STACKED ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_PERCENT ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_DEEP ) );
+}
+
+PieChartDialogController::PieChartDialogController()
+{
+}
+
+PieChartDialogController::~PieChartDialogController()
+{
+}
+
+OUString PieChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_PIE);
+}
+
+OUString PieChartDialogController::getImage()
+{
+ return BMP_TYPE_PIE;
+}
+
+const tTemplateServiceChartTypeParameterMap& PieChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Pie" , ChartTypeParameter(1,false,false)},
+ {"com.sun.star.chart2.template.PieAllExploded" , ChartTypeParameter(2,false,false)},
+ {"com.sun.star.chart2.template.Donut" , ChartTypeParameter(3,false,false)},
+ {"com.sun.star.chart2.template.DonutAllExploded" , ChartTypeParameter(4,false,false)},
+ {"com.sun.star.chart2.template.ThreeDPie" , ChartTypeParameter(1,false,true)},
+ {"com.sun.star.chart2.template.ThreeDPieAllExploded" , ChartTypeParameter(2,false,true)},
+ {"com.sun.star.chart2.template.ThreeDDonut" , ChartTypeParameter(3,false,true)},
+ {"com.sun.star.chart2.template.ThreeDDonutAllExploded" , ChartTypeParameter(4,false,true)}};
+ return s_aTemplateMap;
+}
+void PieChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ if( rParameter.b3DLook )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_CIRCLES_3D));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_CIRCLES_3D_EXPLODED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_DONUT_3D));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_DONUT_3D_EXPLODED));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_CIRCLES_2D));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_CIRCLES_2D_EXPLODED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_DONUT_2D));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_DONUT_2D_EXPLODED));
+ }
+ rSubTypeList.SetItemText( 1, SchResId( STR_NORMAL ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_PIE_EXPLODED ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_DONUT ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_DONUT_EXPLODED ) );
+}
+
+bool PieChartDialogController::shouldShow_3DLookControl() const
+{
+ return true;
+}
+
+void PieChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ if(rParameter.eStackMode==GlobalStackMode_STACK_Z)
+ rParameter.eStackMode = GlobalStackMode_NONE;
+}
+
+LineChartDialogController::LineChartDialogController()
+{
+}
+
+LineChartDialogController::~LineChartDialogController()
+{
+}
+
+OUString LineChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_LINE);
+}
+
+OUString LineChartDialogController::getImage()
+{
+ return BMP_TYPE_LINE;
+}
+
+const tTemplateServiceChartTypeParameterMap& LineChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Symbol" , ChartTypeParameter(1,false,false,GlobalStackMode_NONE,true,false)},
+ {"com.sun.star.chart2.template.StackedSymbol" , ChartTypeParameter(1,false,false,GlobalStackMode_STACK_Y,true,false)},
+ {"com.sun.star.chart2.template.PercentStackedSymbol" , ChartTypeParameter(1,false,false,GlobalStackMode_STACK_Y_PERCENT,true,false)},
+ {"com.sun.star.chart2.template.LineSymbol" , ChartTypeParameter(2,false,false,GlobalStackMode_NONE,true,true)},
+ {"com.sun.star.chart2.template.StackedLineSymbol" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y,true,true)},
+ {"com.sun.star.chart2.template.PercentStackedLineSymbol" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y_PERCENT,true,true)},
+ {"com.sun.star.chart2.template.Line" , ChartTypeParameter(3,false,false,GlobalStackMode_NONE,false,true)},
+ {"com.sun.star.chart2.template.StackedLine" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y,false,true)},
+ {"com.sun.star.chart2.template.PercentStackedLine" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y_PERCENT,false,true)},
+ {"com.sun.star.chart2.template.StackedThreeDLine" , ChartTypeParameter(4,false,true,GlobalStackMode_STACK_Y,false,true)},
+ {"com.sun.star.chart2.template.PercentStackedThreeDLine" , ChartTypeParameter(4,false,true,GlobalStackMode_STACK_Y_PERCENT,false,true)},
+ {"com.sun.star.chart2.template.ThreeDLineDeep" , ChartTypeParameter(4,false,true,GlobalStackMode_STACK_Z,false,true)}};
+ return s_aTemplateMap;
+}
+void LineChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ switch( rParameter.eCurveStyle )
+ {
+ case CurveStyle_CUBIC_SPLINES:
+ case CurveStyle_B_SPLINES:
+ if( rParameter.eStackMode == GlobalStackMode_NONE || rParameter.eStackMode == GlobalStackMode_STACK_Z )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XCATEGORY));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XCATEGORY_SMOOTH));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XCATEGORY_SMOOTH));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XCATEGORY_SMOOTH));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_STACKED));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_STACKED_SMOOTH));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_STACKED_SMOOTH));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_STACKED_SMOOTH));
+ }
+ break;
+ case CurveStyle_STEP_START:
+ case CurveStyle_STEP_END:
+ case CurveStyle_STEP_CENTER_X:
+ case CurveStyle_STEP_CENTER_Y:
+ if( rParameter.eStackMode == GlobalStackMode_NONE || rParameter.eStackMode == GlobalStackMode_STACK_Z )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XCATEGORY));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XCATEGORY_STEPPED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XCATEGORY_STEPPED));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XCATEGORY_STEPPED));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_STACKED));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_STACKED_STEPPED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_STACKED_STEPPED));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_STACKED_STEPPED));
+ }
+ break;
+ default: // includes CurveStyle_LINES
+ //direct lines
+ if( rParameter.eStackMode == GlobalStackMode_NONE || rParameter.eStackMode == GlobalStackMode_STACK_Z )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XCATEGORY));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XCATEGORY));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XCATEGORY));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XCATEGORY));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_STACKED));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_STACKED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_STACKED));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_STACKED));
+ }
+ }
+
+ rSubTypeList.SetItemText( 1, SchResId( STR_POINTS_ONLY ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_POINTS_AND_LINES ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_LINES_ONLY ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_LINES_3D ) );
+}
+bool LineChartDialogController::shouldShow_StackingControl() const
+{
+ return true;
+}
+bool LineChartDialogController::shouldShow_SplineControl() const
+{
+ return true;
+}
+void LineChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.bSymbols = true;
+ rParameter.bLines = true;
+ break;
+ case 3:
+ rParameter.bSymbols = false;
+ rParameter.bLines = true;
+ break;
+ case 4:
+ rParameter.bSymbols = false;
+ rParameter.bLines = true;
+ rParameter.b3DLook = true;
+ if( rParameter.eStackMode == GlobalStackMode_NONE )
+ rParameter.eStackMode = GlobalStackMode_STACK_Z;
+ break;
+ default:
+ rParameter.bSymbols = true;
+ rParameter.bLines = false;
+ break;
+ }
+
+ if(!rParameter.b3DLook && rParameter.eStackMode == GlobalStackMode_STACK_Z )
+ rParameter.eStackMode = GlobalStackMode_NONE;
+}
+void LineChartDialogController::adjustParameterToMainType( ChartTypeParameter& rParameter )
+{
+ if( rParameter.b3DLook && rParameter.eStackMode == GlobalStackMode_NONE )
+ rParameter.eStackMode = GlobalStackMode_STACK_Z;
+
+ ChartTypeDialogController::adjustParameterToMainType( rParameter );
+}
+
+XYChartDialogController::XYChartDialogController()
+{
+ bSupportsXAxisWithValues = true;
+}
+
+XYChartDialogController::~XYChartDialogController()
+{
+}
+
+OUString XYChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_XY);
+}
+
+OUString XYChartDialogController::getImage()
+{
+ return BMP_TYPE_XY;
+}
+
+const tTemplateServiceChartTypeParameterMap& XYChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.ScatterSymbol" , ChartTypeParameter(1,true,false,GlobalStackMode_NONE,true,false)},
+ {"com.sun.star.chart2.template.ScatterLineSymbol" , ChartTypeParameter(2,true,false,GlobalStackMode_NONE,true,true)},
+ {"com.sun.star.chart2.template.ScatterLine" , ChartTypeParameter(3,true,false,GlobalStackMode_NONE,false,true)},
+ {"com.sun.star.chart2.template.ThreeDScatter" , ChartTypeParameter(4,true,true,GlobalStackMode_NONE,false,true)}};
+ return s_aTemplateMap;
+}
+
+void XYChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ switch (rParameter.eCurveStyle)
+ {
+ case CurveStyle_CUBIC_SPLINES:
+ case CurveStyle_B_SPLINES:
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XVALUES));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XVALUES_SMOOTH));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XVALUES_SMOOTH));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XVALUES_SMOOTH));
+ break;
+ }
+ case CurveStyle_STEP_START:
+ case CurveStyle_STEP_END:
+ case CurveStyle_STEP_CENTER_X:
+ case CurveStyle_STEP_CENTER_Y:
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XVALUES));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XVALUES_STEPPED));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XVALUES_STEPPED));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XVALUES_STEPPED));
+ break;
+ }
+ default: // includes CurveStyle_LINES
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_POINTS_XVALUES));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_LINE_P_XVALUES));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_LINE_O_XVALUES));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_LINE3D_XVALUES));
+ }
+
+ rSubTypeList.SetItemText( 1, SchResId( STR_POINTS_ONLY ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_POINTS_AND_LINES ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_LINES_ONLY ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_LINES_3D ) );
+}
+bool XYChartDialogController::shouldShow_SplineControl() const
+{
+ return true;
+}
+bool XYChartDialogController::shouldShow_SortByXValuesResourceGroup() const
+{
+ return true;
+}
+void XYChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.eStackMode=GlobalStackMode_NONE;
+ rParameter.b3DLook = false;
+ rParameter.bXAxisWithValues = true;
+
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.bSymbols = true;
+ rParameter.bLines = true;
+ break;
+ case 3:
+ rParameter.bSymbols = false;
+ rParameter.bLines = true;
+ break;
+ case 4:
+ rParameter.bSymbols = false;
+ rParameter.bLines = true;
+ rParameter.b3DLook = true;
+ rParameter.eStackMode=GlobalStackMode_STACK_Z;
+ break;
+ default:
+ rParameter.bSymbols = true;
+ rParameter.bLines = false;
+ break;
+ }
+}
+
+AreaChartDialogController::AreaChartDialogController()
+{
+}
+
+AreaChartDialogController::~AreaChartDialogController()
+{
+}
+
+OUString AreaChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_AREA);
+}
+
+OUString AreaChartDialogController::getImage()
+{
+ return BMP_TYPE_AREA;
+}
+
+bool AreaChartDialogController::shouldShow_3DLookControl() const
+{
+ return true;
+}
+
+const tTemplateServiceChartTypeParameterMap& AreaChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Area" , ChartTypeParameter(1,false,false,GlobalStackMode_NONE)},
+ {"com.sun.star.chart2.template.ThreeDArea" , ChartTypeParameter(1,false,true,GlobalStackMode_STACK_Z)},
+ {"com.sun.star.chart2.template.StackedArea" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.StackedThreeDArea" , ChartTypeParameter(2,false,true,GlobalStackMode_STACK_Y)},
+ {"com.sun.star.chart2.template.PercentStackedArea" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y_PERCENT)},
+ {"com.sun.star.chart2.template.PercentStackedThreeDArea" , ChartTypeParameter(3,false,true,GlobalStackMode_STACK_Y_PERCENT)}};
+ return s_aTemplateMap;
+}
+
+void AreaChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ if( rParameter.b3DLook )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_AREAS_3D));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_AREAS_3D_1));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_AREAS_3D_2));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_AREAS_2D_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_AREAS_2D));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_AREAS_2D_3));
+ }
+
+ rSubTypeList.SetItemText( 1, SchResId( rParameter.b3DLook ? STR_DEEP : STR_NORMAL ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_STACKED ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_PERCENT ) );
+}
+void AreaChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.eCurveStyle = CurveStyle_LINES;
+
+ if( rParameter.nSubTypeIndex>3 )
+ rParameter.nSubTypeIndex = 1;
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.eStackMode=GlobalStackMode_STACK_Y;
+ break;
+ case 3:
+ rParameter.eStackMode=GlobalStackMode_STACK_Y_PERCENT;
+ break;
+ default:
+ if( rParameter.b3DLook )
+ rParameter.eStackMode=GlobalStackMode_STACK_Z;
+ else
+ rParameter.eStackMode=GlobalStackMode_NONE;
+ break;
+ }
+}
+void AreaChartDialogController::adjustParameterToMainType( ChartTypeParameter& rParameter )
+{
+ if( rParameter.b3DLook && rParameter.eStackMode == GlobalStackMode_NONE )
+ rParameter.eStackMode = GlobalStackMode_STACK_Z;
+
+ ChartTypeDialogController::adjustParameterToMainType( rParameter );
+}
+
+NetChartDialogController::NetChartDialogController()
+{
+ bSupports3D = false;
+}
+
+NetChartDialogController::~NetChartDialogController()
+{
+}
+
+OUString NetChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_NET);
+}
+
+OUString NetChartDialogController::getImage()
+{
+ return BMP_TYPE_NET;
+}
+
+bool NetChartDialogController::shouldShow_StackingControl() const
+{
+ return true;
+}
+
+const tTemplateServiceChartTypeParameterMap& NetChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ //@todo need templates with symbols only
+ {"com.sun.star.chart2.template.NetSymbol" , ChartTypeParameter(1,false,false,GlobalStackMode_NONE,true,false)},
+ {"com.sun.star.chart2.template.StackedNetSymbol" , ChartTypeParameter(1,false,false,GlobalStackMode_STACK_Y,true,false)},
+ {"com.sun.star.chart2.template.PercentStackedNetSymbol" ,ChartTypeParameter(1,false,false,GlobalStackMode_STACK_Y_PERCENT,true,false)},
+
+ {"com.sun.star.chart2.template.Net" , ChartTypeParameter(2,false,false,GlobalStackMode_NONE,true,true)},
+ {"com.sun.star.chart2.template.StackedNet" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y,true,true)},
+ {"com.sun.star.chart2.template.PercentStackedNet" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y_PERCENT,true,true)},
+
+ {"com.sun.star.chart2.template.NetLine" , ChartTypeParameter(3,false,false,GlobalStackMode_NONE,false,true)},
+ {"com.sun.star.chart2.template.StackedNetLine" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y,false,true)},
+ {"com.sun.star.chart2.template.PercentStackedNetLine" , ChartTypeParameter(3,false,false,GlobalStackMode_STACK_Y_PERCENT,false,true)},
+
+ {"com.sun.star.chart2.template.FilledNet" , ChartTypeParameter(4,false,false,GlobalStackMode_NONE,false,false)},
+ {"com.sun.star.chart2.template.StackedFilledNet" , ChartTypeParameter(4,false,false,GlobalStackMode_STACK_Y,false,false)},
+ {"com.sun.star.chart2.template.PercentStackedFilledNet" ,ChartTypeParameter(4,false,false,GlobalStackMode_STACK_Y_PERCENT,false,false)}};
+ return s_aTemplateMap;
+}
+void NetChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& rParameter )
+{
+ rSubTypeList.Clear();
+
+ if( rParameter.eStackMode == GlobalStackMode_NONE )
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_NET_SYMB));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_NET_LINESYMB));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_NET));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_NET_FILL));
+ }
+ else
+ {
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_NET_SYMB_STACK));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_NET_LINESYMB_STACK));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_NET_STACK));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_NET_FILL_STACK));
+ }
+
+ rSubTypeList.SetItemText( 1, SchResId( STR_POINTS_ONLY ) );
+ rSubTypeList.SetItemText( 2, SchResId( STR_POINTS_AND_LINES ) );
+ rSubTypeList.SetItemText( 3, SchResId( STR_LINES_ONLY ) );
+ rSubTypeList.SetItemText( 4, SchResId( STR_FILLED ) );
+}
+void NetChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+ if(rParameter.eStackMode==GlobalStackMode_STACK_Z)
+ rParameter.eStackMode = GlobalStackMode_NONE;
+
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.bSymbols = true;
+ rParameter.bLines = true;
+ break;
+ case 3:
+ rParameter.bSymbols = false;
+ rParameter.bLines = true;
+ break;
+ case 4:
+ rParameter.bSymbols = false;
+ rParameter.bLines = false;
+ break;
+ default:
+ rParameter.bSymbols = true;
+ rParameter.bLines = false;
+ break;
+ }
+}
+StockChartDialogController::StockChartDialogController()
+{
+ bSupports3D = false;
+}
+
+StockChartDialogController::~StockChartDialogController()
+{
+}
+
+OUString StockChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_STOCK);
+}
+
+OUString StockChartDialogController::getImage()
+{
+ return BMP_TYPE_STOCK;
+}
+
+const tTemplateServiceChartTypeParameterMap& StockChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.StockLowHighClose" , ChartTypeParameter(1)},
+ {"com.sun.star.chart2.template.StockOpenLowHighClose" , ChartTypeParameter(2)},
+ {"com.sun.star.chart2.template.StockVolumeLowHighClose" , ChartTypeParameter(3)},
+ {"com.sun.star.chart2.template.StockVolumeOpenLowHighClose" ,ChartTypeParameter(4)}};
+ return s_aTemplateMap;
+}
+
+void StockChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& /*rParameter*/ )
+{
+ rSubTypeList.Clear();
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_STOCK_1));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_STOCK_2));
+ rSubTypeList.InsertItem(3, Image(StockImage::Yes, BMP_STOCK_3));
+ rSubTypeList.InsertItem(4, Image(StockImage::Yes, BMP_STOCK_4));
+
+ rSubTypeList.SetItemText( 1, SchResId(STR_STOCK_1) );
+ rSubTypeList.SetItemText( 2, SchResId(STR_STOCK_2) );
+ rSubTypeList.SetItemText( 3, SchResId(STR_STOCK_3) );
+ rSubTypeList.SetItemText( 4, SchResId(STR_STOCK_4) );
+}
+
+void StockChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+ rParameter.eStackMode = GlobalStackMode_NONE;
+}
+
+CombiColumnLineChartDialogController::CombiColumnLineChartDialogController()
+{
+ bSupports3D = false;
+}
+
+OUString CombiColumnLineChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_COMBI_COLUMN_LINE);
+}
+
+OUString CombiColumnLineChartDialogController::getImage()
+{
+ return BMP_TYPE_COLUMN_LINE;
+}
+
+const tTemplateServiceChartTypeParameterMap& CombiColumnLineChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.ColumnWithLine" , ChartTypeParameter(1)},
+ {"com.sun.star.chart2.template.StackedColumnWithLine" , ChartTypeParameter(2,false,false,GlobalStackMode_STACK_Y)}};
+ return s_aTemplateMap;
+}
+
+void CombiColumnLineChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& /*rParameter*/ )
+{
+ rSubTypeList.Clear();
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_COLUMN_LINE));
+ rSubTypeList.InsertItem(2, Image(StockImage::Yes, BMP_COLUMN_LINE_STACKED));
+
+ rSubTypeList.SetItemText(1, SchResId(STR_LINE_COLUMN));
+ rSubTypeList.SetItemText(2, SchResId(STR_LINE_STACKEDCOLUMN));
+}
+
+void CombiColumnLineChartDialogController::showExtraControls(weld::Builder* pBuilder)
+{
+ if (!m_xFT_NumberOfLines)
+ {
+ m_xFT_NumberOfLines = pBuilder->weld_label("nolinesft");
+ }
+ if (!m_xMF_NumberOfLines)
+ {
+ m_xMF_NumberOfLines = pBuilder->weld_spin_button("nolines");
+
+ m_xMF_NumberOfLines->set_increments(1, 10);
+ m_xMF_NumberOfLines->set_range(1, 100);
+
+ m_xMF_NumberOfLines->connect_value_changed( LINK( this, CombiColumnLineChartDialogController, ChangeLineCountHdl ) );
+ }
+
+ m_xFT_NumberOfLines->show();
+ m_xMF_NumberOfLines->show();
+}
+
+void CombiColumnLineChartDialogController::hideExtraControls() const
+{
+ if (m_xFT_NumberOfLines)
+ m_xFT_NumberOfLines->hide();
+ if (m_xMF_NumberOfLines)
+ m_xMF_NumberOfLines->hide();
+}
+
+void CombiColumnLineChartDialogController::fillExtraControls(
+ const rtl::Reference<::chart::ChartModel>& xChartModel
+ , const uno::Reference< beans::XPropertySet >& xTemplateProps ) const
+{
+ if (!m_xMF_NumberOfLines)
+ return;
+
+ rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
+ if(!xDiagram.is())
+ return;
+
+ sal_Int32 nNumLines = 0;
+
+ if(xTemplateProps.is())
+ {
+ try
+ {
+ xTemplateProps->getPropertyValue( "NumberOfLines" ) >>= nNumLines;
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ if( nNumLines < 0 )
+ nNumLines = 0;
+ m_xMF_NumberOfLines->set_value(nNumLines);
+
+ sal_Int32 nMaxLines = ChartModelHelper::getDataSeries( xChartModel ).size() - 1;
+ if( nMaxLines < 0 )
+ nMaxLines = 0;
+ m_xMF_NumberOfLines->set_max(nMaxLines);
+}
+void CombiColumnLineChartDialogController::setTemplateProperties( const uno::Reference< beans::XPropertySet >& xTemplateProps ) const
+{
+ if( xTemplateProps.is() )
+ {
+ sal_Int32 nNumLines = m_xMF_NumberOfLines->get_value();
+ xTemplateProps->setPropertyValue( "NumberOfLines" , uno::Any(nNumLines) );
+ }
+}
+
+IMPL_LINK_NOARG(CombiColumnLineChartDialogController, ChangeLineCountHdl, weld::SpinButton&, void)
+{
+ if( m_pChangeListener )
+ m_pChangeListener->stateChanged();
+}
+void CombiColumnLineChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+ if(rParameter.eStackMode==GlobalStackMode_STACK_Z)
+ rParameter.eStackMode = GlobalStackMode_NONE;
+
+ switch( rParameter.nSubTypeIndex )
+ {
+ case 2:
+ rParameter.eStackMode=GlobalStackMode_STACK_Y;
+ break;
+ default:
+ rParameter.eStackMode=GlobalStackMode_NONE;
+ break;
+ }
+}
+
+BubbleChartDialogController::BubbleChartDialogController()
+{
+}
+
+BubbleChartDialogController::~BubbleChartDialogController()
+{
+}
+
+OUString BubbleChartDialogController::getName()
+{
+ return SchResId(STR_TYPE_BUBBLE);
+}
+
+OUString BubbleChartDialogController::getImage()
+{
+ return BMP_TYPE_BUBBLE;
+}
+
+const tTemplateServiceChartTypeParameterMap& BubbleChartDialogController::getTemplateMap() const
+{
+ static tTemplateServiceChartTypeParameterMap s_aTemplateMap{
+ {"com.sun.star.chart2.template.Bubble" , ChartTypeParameter(1,true)}};
+ return s_aTemplateMap;
+}
+void BubbleChartDialogController::fillSubTypeList( ValueSet& rSubTypeList, const ChartTypeParameter& /*rParameter*/ )
+{
+ rSubTypeList.Clear();
+ rSubTypeList.InsertItem(1, Image(StockImage::Yes, BMP_BUBBLE_1));
+
+ rSubTypeList.SetItemText( 1, SchResId(STR_BUBBLE_1) );
+}
+void BubbleChartDialogController::adjustParameterToSubType( ChartTypeParameter& rParameter )
+{
+ rParameter.b3DLook = false;
+ rParameter.eStackMode = GlobalStackMode_NONE;
+}
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DataBrowser.cxx b/chart2/source/controller/dialogs/DataBrowser.cxx
new file mode 100644
index 0000000000..30182b95ee
--- /dev/null
+++ b/chart2/source/controller/dialogs/DataBrowser.cxx
@@ -0,0 +1,1376 @@
+/* -*- 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 .
+ */
+
+#include <svl/zforlist.hxx>
+
+#include "DataBrowser.hxx"
+#include "DataBrowserModel.hxx"
+#include <strings.hrc>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <DiagramHelper.hxx>
+#include <CommonConverters.hxx>
+#include <NumberFormatterWrapper.hxx>
+#include <servicenames_charttypes.hxx>
+#include <ResId.hxx>
+#include <bitmaps.hlst>
+#include <helpids.h>
+#include <ChartModel.hxx>
+#include <ChartType.hxx>
+
+#include <vcl/weld.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include <svl/numformat.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <com/sun/star/container/XIndexReplace.hpp>
+
+#include <algorithm>
+#include <limits>
+
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+using namespace ::svt;
+
+namespace
+{
+/* BrowserMode::COLUMNSELECTION : single cells may be selected rather than only
+ entire rows
+ BrowserMode::(H|V)LINES : show horizontal or vertical grid-lines
+ BrowserMode::AUTO_(H|V)SCROLL : scroll automated horizontally or vertically when
+ cursor is moved beyond the edge of the dialog
+ BrowserMode::HIDESELECT : Do not mark the current row with selection color
+ (usually blue)
+ ! BrowserMode::HIDECURSOR would prevent flickering in edit fields, but navigating
+ with shift up/down, and entering non-editable cells would be problematic,
+ e.g. the first cell, or when being in read-only mode
+*/
+const BrowserMode BrowserStdFlags = BrowserMode::COLUMNSELECTION |
+ BrowserMode::HLINES | BrowserMode::VLINES |
+ BrowserMode::AUTO_HSCROLL | BrowserMode::AUTO_VSCROLL |
+ BrowserMode::HIDESELECT;
+
+sal_Int32 lcl_getColumnInData( sal_uInt16 nCol )
+{
+ return static_cast< sal_Int32 >( nCol ) - 1;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+namespace impl
+{
+
+class SeriesHeaderEdit
+{
+public:
+ explicit SeriesHeaderEdit(std::unique_ptr<weld::Entry> xControl);
+
+ void setStartColumn( sal_Int32 nStartColumn );
+ sal_Int32 getStartColumn() const { return m_nStartColumn;}
+ void SetShowWarningBox( bool bShowWarning );
+
+ OUString GetText() const { return m_xControl->get_text(); }
+ void SetText(const OUString& rText) { m_xControl->set_text(rText); }
+
+ bool HasFocus() const { return m_xControl->has_focus(); }
+
+ void set_size_request(int nWidth, int nHeight) { m_xControl->set_size_request(nWidth, nHeight); }
+ void set_margin_start(int nLeft) { m_xControl->set_margin_start(nLeft); }
+
+ void SetModifyHdl(const Link<SeriesHeaderEdit&,void>& rLink) { m_aModifyHdl = rLink; }
+ void SetGetFocusHdl(const Link<SeriesHeaderEdit&,void>& rLink) { m_aFocusInHdl = rLink; }
+
+private:
+ DECL_LINK(NameEdited, weld::Entry&, void);
+ DECL_LINK(NameFocusIn, weld::Widget&, void);
+ DECL_LINK(MousePressHdl, const MouseEvent&, bool);
+
+ std::unique_ptr<weld::Entry> m_xControl;
+ Link<SeriesHeaderEdit&,void> m_aModifyHdl;
+ Link<SeriesHeaderEdit&,void> m_aFocusInHdl;
+ sal_Int32 m_nStartColumn;
+ bool m_bShowWarningBox;
+};
+
+SeriesHeaderEdit::SeriesHeaderEdit(std::unique_ptr<weld::Entry> xControl)
+ : m_xControl(std::move(xControl))
+ , m_nStartColumn(0)
+ , m_bShowWarningBox(false)
+{
+ m_xControl->set_help_id(HID_SCH_DATA_SERIES_LABEL);
+ m_xControl->connect_changed(LINK(this, SeriesHeaderEdit, NameEdited));
+ m_xControl->connect_focus_in(LINK(this, SeriesHeaderEdit, NameFocusIn));
+ m_xControl->connect_mouse_press(LINK(this, SeriesHeaderEdit, MousePressHdl));
+}
+
+IMPL_LINK_NOARG(SeriesHeaderEdit, NameEdited, weld::Entry&, void)
+{
+ m_aModifyHdl.Call(*this);
+}
+
+IMPL_LINK_NOARG(SeriesHeaderEdit, NameFocusIn, weld::Widget&, void)
+{
+ m_aFocusInHdl.Call(*this);
+}
+
+void SeriesHeaderEdit::setStartColumn( sal_Int32 nStartColumn )
+{
+ m_nStartColumn = nStartColumn;
+}
+
+void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning )
+{
+ m_bShowWarningBox = bShowWarning;
+}
+
+IMPL_LINK_NOARG(SeriesHeaderEdit, MousePressHdl, const MouseEvent&, bool)
+{
+ if (m_bShowWarningBox)
+ {
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xControl.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ SchResId(STR_INVALID_NUMBER)));
+ xWarn->run();
+ }
+
+ return false;
+}
+
+class SeriesHeader
+{
+public:
+ explicit SeriesHeader(weld::Container* pParent, weld::Container* pColorParent);
+ ~SeriesHeader();
+
+ void SetColor( const Color & rCol );
+ void SetPos();
+ void SetWidth( sal_Int32 nWidth );
+ void SetChartType( const rtl::Reference< ::chart::ChartType > & xChartType,
+ bool bSwapXAndYAxis );
+ void SetSeriesName( const OUString & rName );
+ void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol );
+
+ void SetPixelWidth( sal_Int32 nWidth );
+
+ sal_Int32 GetStartColumn() const { return m_nStartCol;}
+ sal_Int32 GetEndColumn() const { return m_nEndCol;}
+
+ static const sal_Int32 nSymbolHeight = 10;
+ static const sal_Int32 nSymbolDistance = 2;
+
+ static sal_Int32 GetRelativeAppFontXPosForNameField() { return nSymbolHeight + nSymbolDistance; }
+
+ void Show();
+ void Hide();
+
+ /** call this before destroying the class. This notifies the listeners to
+ changes of the edit field for the series name.
+ */
+ void applyChanges();
+
+ void SetGetFocusHdl(const Link<SeriesHeaderEdit&,void>& rLink);
+
+ void SetEditChangedHdl( const Link<SeriesHeaderEdit&,void> & rLink );
+
+ bool HasFocus() const;
+
+private:
+ Timer m_aUpdateDataTimer;
+
+ std::unique_ptr<weld::Builder> m_xBuilder1;
+ std::unique_ptr<weld::Builder> m_xBuilder2;
+
+ weld::Container* m_pParent;
+ weld::Container* m_pColorParent;
+
+ std::unique_ptr<weld::Container> m_xContainer1;
+ std::unique_ptr<weld::Container> m_xContainer2;
+ std::unique_ptr<weld::Image> m_spSymbol;
+ std::unique_ptr<SeriesHeaderEdit> m_spSeriesName;
+ std::unique_ptr<weld::Image> m_spColorBar;
+ VclPtr< OutputDevice> m_xDevice;
+ Link<SeriesHeaderEdit&,void> m_aChangeLink;
+ Color m_aColor;
+
+ void notifyChanges();
+ DECL_LINK( ImplUpdateDataHdl, Timer*, void );
+ DECL_LINK( SeriesNameEdited, SeriesHeaderEdit&, void );
+
+ static OUString GetChartTypeImage(
+ const rtl::Reference< ::chart::ChartType > & xChartType,
+ bool bSwapXAndYAxis
+ );
+
+ sal_Int32 m_nStartCol, m_nEndCol;
+ sal_Int32 m_nWidth;
+ bool m_bSeriesNameChangePending;
+};
+
+SeriesHeader::SeriesHeader(weld::Container* pParent, weld::Container* pColorParent)
+ : m_aUpdateDataTimer( "SeriesHeader UpdateDataTimer" )
+ , m_xBuilder1(Application::CreateBuilder(pParent, "modules/schart/ui/columnfragment.ui"))
+ , m_xBuilder2(Application::CreateBuilder(pColorParent, "modules/schart/ui/imagefragment.ui"))
+ , m_pParent(pParent)
+ , m_pColorParent(pColorParent)
+ , m_xContainer1(m_xBuilder1->weld_container("container"))
+ , m_xContainer2(m_xBuilder2->weld_container("container"))
+ , m_spSymbol(m_xBuilder1->weld_image("image"))
+ , m_spSeriesName(new SeriesHeaderEdit(m_xBuilder1->weld_entry("entry")))
+ , m_spColorBar(m_xBuilder2->weld_image("image"))
+ , m_xDevice(Application::GetDefaultDevice())
+ , m_nStartCol( 0 )
+ , m_nEndCol( 0 )
+ , m_nWidth( 42 )
+ , m_bSeriesNameChangePending( false )
+{
+ m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SeriesHeader, ImplUpdateDataHdl));
+ m_aUpdateDataTimer.SetTimeout(4 * EDIT_UPDATEDATA_TIMEOUT);
+
+ m_spSeriesName->SetModifyHdl(LINK(this, SeriesHeader, SeriesNameEdited));
+ Show();
+}
+
+SeriesHeader::~SeriesHeader()
+{
+ m_aUpdateDataTimer.Stop();
+ m_pParent->move(m_xContainer1.get(), nullptr);
+ m_pColorParent->move(m_xContainer2.get(), nullptr);
+}
+
+void SeriesHeader::notifyChanges()
+{
+ m_aChangeLink.Call(*m_spSeriesName);
+ m_bSeriesNameChangePending = false;
+}
+
+void SeriesHeader::applyChanges()
+{
+ if( m_bSeriesNameChangePending )
+ {
+ notifyChanges();
+ }
+}
+
+void SeriesHeader::SetColor( const Color & rCol )
+{
+ m_aColor = rCol;
+}
+
+void SeriesHeader::SetPos()
+{
+ // chart type symbol
+ Size aSize( nSymbolHeight, nSymbolHeight );
+ aSize = m_xDevice->LogicToPixel(aSize, MapMode(MapUnit::MapAppFont));
+ m_spSymbol->set_size_request(aSize.Width(), aSize.Height());
+
+ // series name edit field
+ m_spSeriesName->set_margin_start(2);
+
+ sal_Int32 nHeightPx = m_xDevice->LogicToPixel(Size(0, 12), MapMode(MapUnit::MapAppFont)).Height();
+ m_spSeriesName->set_size_request(m_nWidth - aSize.Width() - 2, nHeightPx);
+
+ // color bar
+ nHeightPx = m_xDevice->LogicToPixel(Size(0, 3), MapMode(MapUnit::MapAppFont)).Height();
+ m_spColorBar->set_size_request(m_nWidth, nHeightPx);
+
+ ScopedVclPtr<VirtualDevice> xVirDev(m_spColorBar->create_virtual_device());
+ xVirDev->SetOutputSizePixel(Size(m_nWidth, nHeightPx));
+ xVirDev->SetFillColor(m_aColor);
+ xVirDev->SetLineColor(m_aColor);
+ xVirDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
+ m_spColorBar->set_image(xVirDev.get());
+}
+
+void SeriesHeader::SetWidth( sal_Int32 nWidth )
+{
+ m_nWidth = nWidth;
+ SetPos();
+}
+
+void SeriesHeader::SetPixelWidth( sal_Int32 nWidth )
+{
+ SetWidth(nWidth);
+}
+
+void SeriesHeader::SetChartType(
+ const rtl::Reference< ChartType > & xChartType,
+ bool bSwapXAndYAxis
+)
+{
+ m_spSymbol->set_from_icon_name( GetChartTypeImage( xChartType, bSwapXAndYAxis ) );
+}
+
+void SeriesHeader::SetSeriesName( const OUString & rName )
+{
+ m_spSeriesName->SetText(rName);
+}
+
+void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol )
+{
+ m_nStartCol = nStartCol;
+ m_nEndCol = std::max(nEndCol, nStartCol);
+ m_spSeriesName->setStartColumn( nStartCol );
+}
+
+void SeriesHeader::Show()
+{
+ m_xContainer1->show();
+ m_xContainer2->show();
+}
+
+void SeriesHeader::Hide()
+{
+ m_xContainer1->hide();
+ m_xContainer2->hide();
+}
+
+void SeriesHeader::SetEditChangedHdl( const Link<SeriesHeaderEdit&,void> & rLink )
+{
+ m_aChangeLink = rLink;
+}
+
+IMPL_LINK_NOARG(SeriesHeader, ImplUpdateDataHdl, Timer*, void)
+{
+ notifyChanges();
+}
+
+IMPL_LINK_NOARG(SeriesHeader, SeriesNameEdited, SeriesHeaderEdit&, void)
+{
+ m_bSeriesNameChangePending = true;
+ m_aUpdateDataTimer.Start();
+}
+
+void SeriesHeader::SetGetFocusHdl( const Link<SeriesHeaderEdit&,void>& rLink )
+{
+ m_spSeriesName->SetGetFocusHdl( rLink );
+}
+
+bool SeriesHeader::HasFocus() const
+{
+ return m_spSeriesName->HasFocus();
+}
+
+OUString SeriesHeader::GetChartTypeImage(
+ const rtl::Reference< ChartType > & xChartType,
+ bool bSwapXAndYAxis
+)
+{
+ OUString aResult;
+ if( !xChartType.is())
+ return aResult;
+ OUString aChartTypeName( xChartType->getChartType());
+
+ if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_AREA )
+ {
+ aResult = BMP_TYPE_AREA;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )
+ {
+ if( bSwapXAndYAxis )
+ aResult = BMP_TYPE_BAR;
+ else
+ aResult = BMP_TYPE_COLUMN;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_LINE )
+ {
+ aResult = BMP_TYPE_LINE;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )
+ {
+ aResult = BMP_TYPE_XY;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_PIE )
+ {
+ aResult = BMP_TYPE_PIE;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_NET
+ || aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET )
+ {
+ aResult = BMP_TYPE_NET;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )
+ {
+ // @todo: correct image for candle-stick type
+ aResult = BMP_TYPE_STOCK;
+ }
+ else if( aChartTypeName == CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE )
+ {
+ aResult = BMP_TYPE_BUBBLE;
+ }
+
+ return aResult;
+}
+
+} // namespace impl
+
+namespace
+{
+
+/** returns false, if no header as the focus.
+
+ If a header has the focus, true is returned and the index of the header
+ with focus is set at pIndex if pOutIndex is not 0.
+*/
+bool lcl_SeriesHeaderHasFocus(
+ const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader,
+ sal_Int32 * pOutIndex = nullptr )
+{
+ sal_Int32 nIndex = 0;
+ for (auto const& elem : rSeriesHeader)
+ {
+ if(elem->HasFocus())
+ {
+ if( pOutIndex )
+ *pOutIndex = nIndex;
+ return true;
+ }
+ ++nIndex;
+ }
+ return false;
+}
+
+sal_Int32 lcl_getColumnInDataOrHeader(
+ sal_uInt16 nCol, const std::vector< std::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader )
+{
+ sal_Int32 nColIdx = 0;
+ bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx ));
+
+ if( bHeaderHasFocus )
+ nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn()));
+ else
+ nColIdx = lcl_getColumnInData( nCol );
+
+ return nColIdx;
+}
+
+} // anonymous namespace
+
+DataBrowser::DataBrowser(const css::uno::Reference<css::awt::XWindow> &rParent,
+ weld::Container* pColumns, weld::Container* pColors) :
+ ::svt::EditBrowseBox(VCLUnoHelper::GetWindow(rParent),
+ EditBrowseBoxFlags::SMART_TAB_TRAVEL | EditBrowseBoxFlags::HANDLE_COLUMN_TEXT,
+ WB_BORDER | WB_TABSTOP, BrowserStdFlags ),
+ m_nSeekRow( 0 ),
+ m_bIsReadOnly( false ),
+ m_bDataValid( true ),
+ m_aNumberEditField(VclPtr<FormattedControl>::Create(&EditBrowseBox::GetDataWindow(), false)),
+ m_aTextEditField(VclPtr<EditControl>::Create(&EditBrowseBox::GetDataWindow())),
+ m_pColumnsWin(pColumns),
+ m_pColorsWin(pColors),
+ m_rNumberEditController( new ::svt::FormattedFieldCellController( m_aNumberEditField.get() )),
+ m_rTextEditController( new ::svt::EditCellController( m_aTextEditField.get() ))
+{
+ Formatter& rFormatter = m_aNumberEditField->get_formatter();
+ rFormatter.SetDefaultValue( std::numeric_limits<double>::quiet_NaN() );
+ rFormatter.TreatAsNumber( true );
+ RenewTable();
+}
+
+DataBrowser::~DataBrowser()
+{
+ disposeOnce();
+}
+
+void DataBrowser::dispose()
+{
+ m_aSeriesHeaders.clear();
+ m_aNumberEditField.disposeAndClear();
+ m_aTextEditField.disposeAndClear();
+ ::svt::EditBrowseBox::dispose();
+}
+
+bool DataBrowser::MayInsertRow() const
+{
+ return ! IsReadOnly()
+ && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ));
+}
+
+bool DataBrowser::MayInsertColumn() const
+{
+ return ! IsReadOnly();
+}
+
+bool DataBrowser::MayDeleteRow() const
+{
+ return ! IsReadOnly()
+ && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
+ && ( GetCurRow() >= 0 )
+ && ( GetRowCount() > 1 );
+}
+
+bool DataBrowser::MayDeleteColumn() const
+{
+ // if a series header has the focus
+ if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
+ return true;
+
+ return ! IsReadOnly()
+ && ( GetCurColumnId() > 1 )
+ && ( ColCount() > 2 );
+}
+
+bool DataBrowser::MayMoveUpRows() const
+{
+ return ! IsReadOnly()
+ && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
+ && ( GetCurRow() > 0 )
+ && ( GetCurRow() <= GetRowCount() - 1 );
+}
+
+bool DataBrowser::MayMoveDownRows() const
+{
+ return ! IsReadOnly()
+ && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders ))
+ && ( GetCurRow() >= 0 )
+ && ( GetCurRow() < GetRowCount() - 1 );
+}
+
+bool DataBrowser::MayMoveLeftColumns() const
+{
+ // if a series header (except the last one) has the focus
+ {
+ sal_Int32 nColIndex(0);
+ if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
+ return (o3tl::make_unsigned( nColIndex ) <= (m_aSeriesHeaders.size() - 1)) && (static_cast< sal_uInt32 >( nColIndex ) != 0);
+ }
+
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+ return ! IsReadOnly()
+ && ( nColIdx > 1 )
+ && ( nColIdx <= ColCount() - 2 )
+ && m_apDataBrowserModel
+ && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
+}
+
+bool DataBrowser::MayMoveRightColumns() const
+{
+ // if a series header (except the last one) has the focus
+ {
+ sal_Int32 nColIndex(0);
+ if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex ))
+ return (o3tl::make_unsigned( nColIndex ) < (m_aSeriesHeaders.size() - 1));
+ }
+
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+ return ! IsReadOnly()
+ && ( nColIdx > 0 )
+ && ( nColIdx < ColCount()-2 )
+ && m_apDataBrowserModel
+ && !m_apDataBrowserModel->isCategoriesColumn( nColIdx );
+}
+
+void DataBrowser::clearHeaders()
+{
+ for( const auto& spHeader : m_aSeriesHeaders )
+ spHeader->applyChanges();
+ m_aSeriesHeaders.clear();
+}
+
+void DataBrowser::RenewTable()
+{
+ if (!m_apDataBrowserModel)
+ return;
+
+ sal_Int32 nOldRow = GetCurRow();
+ sal_uInt16 nOldColId = GetCurColumnId();
+
+ bool bLastUpdateMode = GetUpdateMode();
+ SetUpdateMode( false );
+
+ if( IsModified() )
+ SaveModified();
+
+ DeactivateCell();
+
+ RemoveColumns();
+ RowRemoved( 1, GetRowCount() );
+
+ // for row numbers
+ InsertHandleColumn( static_cast< sal_uInt16 >(
+ GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() ));
+
+ OUString aDefaultSeriesName(SchResId(STR_COLUMN_LABEL));
+ replaceParamterInString( aDefaultSeriesName, u"%COLUMNNUMBER", OUString::number( 24 ) );
+ sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName )
+ + GetDataWindow().LogicToPixel(Point(8 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0), MapMode(MapUnit::MapAppFont)).X();
+ sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount();
+ // nRowCount is a member of a base class
+ sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount();
+ for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx )
+ {
+ InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth );
+ }
+
+ RowInserted( 1, nRowCountLocal );
+ GoToRow( std::min( nOldRow, GetRowCount() - 1 ));
+ GoToColumnId( std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 )));
+
+ // fill series headers
+ clearHeaders();
+ const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders());
+ Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
+ Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
+
+ for (auto const& elemHeader : aHeaders)
+ {
+ auto spHeader = std::make_shared<impl::SeriesHeader>( m_pColumnsWin, m_pColorsWin );
+ Color nColor;
+ // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc.
+ if( elemHeader.m_xDataSeries.is() &&
+ ( elemHeader.m_xDataSeries->getPropertyValue( "Color" ) >>= nColor ))
+ spHeader->SetColor( nColor );
+ spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
+ spHeader->SetSeriesName(
+ elemHeader.m_xDataSeries->getLabelForRole(
+ elemHeader.m_xChartType.is() ?
+ elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
+ OUString("values-y")));
+ // index is 1-based, as 0 is for the column that contains the row-numbers
+ spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
+ spHeader->SetGetFocusHdl( aFocusLink );
+ spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
+ m_aSeriesHeaders.push_back( spHeader );
+ }
+
+ ImplAdjustHeaderControls();
+ SetUpdateMode( bLastUpdateMode );
+ ActivateCell();
+ Invalidate();
+}
+
+OUString DataBrowser::GetColString( sal_Int32 nColumnId ) const
+{
+ OSL_ASSERT(m_apDataBrowserModel);
+ if( nColumnId > 0 )
+ return m_apDataBrowserModel->getRoleOfColumn( nColumnId - 1 );
+ return OUString();
+}
+
+OUString DataBrowser::GetCellText( sal_Int32 nRow, sal_uInt16 nColumnId ) const
+{
+ OUString aResult;
+
+ if( nColumnId == 0 )
+ {
+ aResult = OUString::number(nRow + 1);
+ }
+ else if( nRow >= 0 && m_apDataBrowserModel)
+ {
+ sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1;
+
+ if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::NUMBER )
+ {
+ double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow ));
+
+ if( ! std::isnan( fData ) &&
+ m_spNumberFormatterWrapper )
+ {
+ bool bColorChanged = false;
+ Color nLabelColor;
+ aResult = m_spNumberFormatterWrapper->getFormattedString(
+ GetNumberFormatKey( nColumnId ),
+ fData, nLabelColor, bColorChanged );
+ }
+ }
+ else if( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXTORDATE )
+ {
+ uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow );
+ OUString aText;
+ double fDouble=0.0;
+ if( aAny>>=aText )
+ aResult = aText;
+ else if( aAny>>=fDouble )
+ {
+ if( ! std::isnan( fDouble ) && m_spNumberFormatterWrapper )
+ {
+ // If a numberformat was available here we could directly
+ // obtain the corresponding edit format in
+ // getDateTimeInputNumberFormat() instead of doing the
+ // guess work.
+ sal_Int32 nNumberFormat = DiagramHelper::getDateTimeInputNumberFormat(
+ m_xChartDoc, fDouble );
+ Color nLabelColor;
+ bool bColorChanged = false;
+ aResult = m_spNumberFormatterWrapper->getFormattedString(
+ nNumberFormat, fDouble, nLabelColor, bColorChanged );
+ }
+ }
+ }
+ else
+ {
+ OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex ) == DataBrowserModel::TEXT );
+ aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow );
+ }
+ }
+
+ return aResult;
+}
+
+double DataBrowser::GetCellNumber( sal_Int32 nRow, sal_uInt16 nColumnId ) const
+{
+ if(( nColumnId >= 1 ) && ( nRow >= 0 ) && m_apDataBrowserModel)
+ {
+ return m_apDataBrowserModel->getCellNumber(
+ static_cast< sal_Int32 >( nColumnId ) - 1, nRow );
+ }
+
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+void DataBrowser::Resize()
+{
+ bool bLastUpdateMode = GetUpdateMode();
+ SetUpdateMode( false );
+
+ ::svt::EditBrowseBox::Resize();
+ ImplAdjustHeaderControls();
+ SetUpdateMode( bLastUpdateMode );
+}
+
+void DataBrowser::SetReadOnly( bool bNewState )
+{
+ if( m_bIsReadOnly != bNewState )
+ {
+ m_bIsReadOnly = bNewState;
+ Invalidate();
+ DeactivateCell();
+ }
+}
+
+void DataBrowser::CursorMoved()
+{
+ EditBrowseBox::CursorMoved();
+
+ if( GetUpdateMode() )
+ m_aCursorMovedHdlLink.Call( this );
+}
+
+void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt )
+{
+ if( !m_bDataValid )
+ ShowWarningBox();
+ else
+ EditBrowseBox::MouseButtonDown( rEvt );
+}
+
+void DataBrowser::ShowWarningBox()
+{
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ SchResId(STR_INVALID_NUMBER)));
+ xWarn->run();
+}
+
+bool DataBrowser::ShowQueryBox()
+{
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ SchResId(STR_DATA_EDITOR_INCORRECT_INPUT)));
+ return xQueryBox->run() == RET_YES;
+}
+
+bool DataBrowser::IsDataValid() const
+{
+ bool bValid = true;
+ const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
+
+ if( m_apDataBrowserModel->getCellType( nCol ) == DataBrowserModel::NUMBER )
+ {
+ sal_uInt32 nDummy = 0;
+ double fDummy = 0.0;
+ OUString aText(m_aNumberEditField->get_widget().get_text());
+
+ if( !aText.isEmpty() &&
+ m_spNumberFormatterWrapper &&
+ m_spNumberFormatterWrapper->getSvNumberFormatter() &&
+ ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat(
+ aText, nDummy, fDummy ))
+ {
+ bValid = false;
+ }
+ }
+
+ return bValid;
+}
+
+void DataBrowser::CellModified()
+{
+ m_bDataValid = IsDataValid();
+ m_aCursorMovedHdlLink.Call( this );
+}
+
+void DataBrowser::SetDataFromModel(
+ const rtl::Reference<::chart::ChartModel> & xChartDoc )
+{
+ m_xChartDoc = xChartDoc;
+
+ m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc ));
+ m_spNumberFormatterWrapper =
+ std::make_shared<NumberFormatterWrapper>(m_xChartDoc);
+
+ Formatter& rFormatter = m_aNumberEditField->get_formatter();
+ rFormatter.SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() );
+
+ RenewTable();
+
+ const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount();
+ const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount();
+ if( nRowCnt && nColCnt )
+ {
+ GoToRow( 0 );
+ GoToColumnId( 1 );
+ }
+}
+
+void DataBrowser::InsertColumn()
+{
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+
+ if( nColIdx >= 0 && m_apDataBrowserModel)
+ {
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->insertDataSeries( nColIdx );
+ RenewTable();
+ }
+}
+
+void DataBrowser::InsertTextColumn()
+{
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+
+ if( nColIdx >= 0 && m_apDataBrowserModel)
+ {
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx );
+ RenewTable();
+ }
+}
+
+void DataBrowser::RemoveColumn()
+{
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+
+ if( nColIdx >= 0 && m_apDataBrowserModel)
+ {
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_bDataValid = true;
+ m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx );
+ RenewTable();
+ }
+}
+
+void DataBrowser::InsertRow()
+{
+ sal_Int32 nRowIdx = GetCurRow();
+
+ if( nRowIdx >= 0 && m_apDataBrowserModel)
+ {
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx );
+ RenewTable();
+ }
+}
+
+void DataBrowser::RemoveRow()
+{
+ sal_Int32 nRowIdx = GetCurRow();
+
+ if( nRowIdx >= 0 && m_apDataBrowserModel)
+ {
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_bDataValid = true;
+ m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx );
+ RenewTable();
+ }
+}
+
+void DataBrowser::MoveLeftColumn()
+{
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+
+ if( !(nColIdx > 0 && m_apDataBrowserModel))
+ return;
+
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->swapDataSeries( nColIdx - 1 );
+
+ // keep cursor in swapped column
+ if(( 0 < GetCurColumnId() ) && ( GetCurColumnId() <= ColCount() - 1 ))
+ {
+ Dispatch( BROWSER_CURSORLEFT );
+ }
+ RenewTable();
+}
+
+void DataBrowser::MoveRightColumn()
+{
+ sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders );
+
+ if( !(nColIdx >= 0 && m_apDataBrowserModel))
+ return;
+
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->swapDataSeries( nColIdx );
+
+ // keep cursor in swapped column
+ if( GetCurColumnId() < ColCount() - 1 )
+ {
+ Dispatch( BROWSER_CURSORRIGHT );
+ }
+ RenewTable();
+}
+
+void DataBrowser::MoveUpRow()
+{
+ sal_Int32 nRowIdx = GetCurRow();
+
+ if( !(nRowIdx > 0 && m_apDataBrowserModel))
+ return;
+
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx - 1 );
+
+ // keep cursor in swapped row
+ if(( 0 < GetCurRow() ) && ( GetCurRow() <= GetRowCount() - 1 ))
+ {
+ Dispatch( BROWSER_CURSORUP );
+ }
+ RenewTable();
+}
+
+void DataBrowser::MoveDownRow()
+{
+ sal_Int32 nRowIdx = GetCurRow();
+
+ if( !(nRowIdx >= 0 && m_apDataBrowserModel))
+ return;
+
+ // save changes made to edit-field
+ if( IsModified() )
+ SaveModified();
+
+ m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx );
+
+ // keep cursor in swapped row
+ if( GetCurRow() < GetRowCount() - 1 )
+ {
+ Dispatch( BROWSER_CURSORDOWN );
+ }
+ RenewTable();
+}
+
+void DataBrowser::SetCursorMovedHdl( const Link<DataBrowser*,void>& rLink )
+{
+ m_aCursorMovedHdlLink = rLink;
+}
+
+// implementations for ::svt::EditBrowseBox (pure virtual methods)
+void DataBrowser::PaintCell(
+ OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const
+{
+ Point aPos( rRect.TopLeft());
+ aPos.AdjustX(1 );
+
+ OUString aText = GetCellText( m_nSeekRow, nColumnId );
+ Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight());
+
+ // clipping
+ if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() ||
+ aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom())
+ rDev.SetClipRegion(vcl::Region(rRect));
+
+ // allow for a disabled control ...
+ bool bEnabled = IsEnabled();
+ Color aOriginalColor = rDev.GetTextColor();
+ if( ! bEnabled )
+ rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
+
+ // draw the text
+ rDev.DrawText( aPos, aText );
+
+ // reset the color (if necessary)
+ if( ! bEnabled )
+ rDev.SetTextColor( aOriginalColor );
+
+ if( rDev.IsClipRegion())
+ rDev.SetClipRegion();
+}
+
+bool DataBrowser::SeekRow( sal_Int32 nRow )
+{
+ if( ! EditBrowseBox::SeekRow( nRow ))
+ return false;
+
+ if( nRow < 0 )
+ m_nSeekRow = - 1;
+ else
+ m_nSeekRow = nRow;
+
+ return true;
+}
+
+bool DataBrowser::IsTabAllowed( bool bForward ) const
+{
+ sal_Int32 nRow = GetCurRow();
+ sal_Int32 nCol = GetCurColumnId();
+
+ // column 0 is header-column
+ sal_Int32 nBadCol = bForward
+ ? GetColumnCount() - 1
+ : 1;
+ sal_Int32 nBadRow = bForward
+ ? GetRowCount() - 1
+ : 0;
+
+ if( !m_bDataValid )
+ {
+ const_cast< DataBrowser* >( this )->ShowWarningBox();
+ return false;
+ }
+
+ return ( nRow != nBadRow ||
+ nCol != nBadCol );
+}
+
+::svt::CellController* DataBrowser::GetController( sal_Int32 /*nRow*/, sal_uInt16 nCol )
+{
+ if( m_bIsReadOnly )
+ return nullptr;
+
+ if( CellContainsNumbers( nCol ))
+ {
+ Formatter& rFormatter = m_aNumberEditField->get_formatter();
+ rFormatter.UseInputStringForFormatting();
+ rFormatter.SetFormatKey( GetNumberFormatKey( nCol ));
+ return m_rNumberEditController.get();
+ }
+
+ return m_rTextEditController.get();
+}
+
+void DataBrowser::InitController(
+ ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol )
+{
+ if( rController == m_rTextEditController )
+ {
+ OUString aText( GetCellText( nRow, nCol ) );
+ weld::Entry& rEntry = m_aTextEditField->get_widget();
+ rEntry.set_text(aText);
+ rEntry.select_region(0, -1);
+ }
+ else if( rController == m_rNumberEditController )
+ {
+ // treat invalid and empty text as Nan
+ Formatter& rFormatter = m_aNumberEditField->get_formatter();
+ rFormatter.EnableNotANumber( true );
+ if( std::isnan( GetCellNumber( nRow, nCol )))
+ rFormatter.SetTextValue( OUString());
+ else
+ rFormatter.SetValue( GetCellNumber( nRow, nCol ) );
+ weld::Entry& rEntry = m_aNumberEditField->get_widget();
+ rEntry.select_region(0, -1);
+ }
+ else
+ {
+ OSL_FAIL( "Invalid Controller" );
+ }
+}
+
+bool DataBrowser::CellContainsNumbers( sal_uInt16 nCol ) const
+{
+ if (!m_apDataBrowserModel)
+ return false;
+ return m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol )) == DataBrowserModel::NUMBER;
+}
+
+sal_uInt32 DataBrowser::GetNumberFormatKey( sal_uInt16 nCol ) const
+{
+ if (!m_apDataBrowserModel)
+ return 0;
+ return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ) );
+}
+
+bool DataBrowser::isDateTimeString( const OUString& aInputString, double& fOutDateTimeValue )
+{
+ sal_uInt32 nNumberFormat=0;
+ SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
+ if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateTimeValue ) )
+ {
+ SvNumFormatType nType = pSvNumberFormatter->GetType( nNumberFormat);
+ return (nType & SvNumFormatType::DATE) || (nType & SvNumFormatType::TIME);
+ }
+ return false;
+}
+
+bool DataBrowser::SaveModified()
+{
+ if( ! IsModified() )
+ return true;
+
+ bool bChangeValid = true;
+
+ const sal_Int32 nRow = GetCurRow();
+ const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId());
+
+ OSL_ENSURE( nRow >= 0 || nCol >= 0, "This cell should not be modified!" );
+
+ SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper ? m_spNumberFormatterWrapper->getSvNumberFormatter() : nullptr;
+ switch( m_apDataBrowserModel->getCellType( nCol ))
+ {
+ case DataBrowserModel::NUMBER:
+ {
+ sal_uInt32 nDummy = 0;
+ double fDummy = 0.0;
+ OUString aText(m_aNumberEditField->get_widget().get_text());
+ // an empty string is valid, if no numberformatter exists, all
+ // values are treated as valid
+ if( !aText.isEmpty() && pSvNumberFormatter &&
+ ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) )
+ {
+ bChangeValid = false;
+ }
+ else
+ {
+ Formatter& rFormatter = m_aNumberEditField->get_formatter();
+ double fData = rFormatter.GetValue();
+ bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData );
+ }
+ }
+ break;
+ case DataBrowserModel::TEXTORDATE:
+ {
+ weld::Entry& rEntry = m_aTextEditField->get_widget();
+ OUString aText(rEntry.get_text());
+ double fValue = 0.0;
+ bChangeValid = false;
+ if( isDateTimeString( aText, fValue ) )
+ bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( fValue ) );
+ if(!bChangeValid)
+ bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::Any( aText ) );
+ }
+ break;
+ case DataBrowserModel::TEXT:
+ {
+ weld::Entry& rEntry = m_aTextEditField->get_widget();
+ OUString aText(rEntry.get_text());
+ bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText );
+ }
+ break;
+ }
+
+ // the first valid change changes this to true
+ if( bChangeValid )
+ {
+ RowModified( GetCurRow(), GetCurColumnId());
+ ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId());
+ if( pCtrl )
+ pCtrl->SaveValue();
+ }
+
+ return bChangeValid;
+}
+
+bool DataBrowser::EndEditing()
+{
+ SaveModified();
+
+ // apply changes made to series headers
+ for( const auto& spHeader : m_aSeriesHeaders )
+ spHeader->applyChanges();
+
+ if( m_bDataValid )
+ return true;
+ else
+ return ShowQueryBox();
+}
+
+void DataBrowser::ColumnResized( sal_uInt16 nColId )
+{
+ bool bLastUpdateMode = GetUpdateMode();
+ SetUpdateMode( false );
+
+ EditBrowseBox::ColumnResized( nColId );
+ ImplAdjustHeaderControls();
+ SetUpdateMode( bLastUpdateMode );
+}
+
+void DataBrowser::EndScroll()
+{
+ bool bLastUpdateMode = GetUpdateMode();
+ SetUpdateMode( false );
+
+ EditBrowseBox::EndScroll();
+ RenewSeriesHeaders();
+
+ SetUpdateMode( bLastUpdateMode );
+}
+
+void DataBrowser::RenewSeriesHeaders()
+{
+ clearHeaders();
+ DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders());
+ Link<impl::SeriesHeaderEdit&,void> aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus ));
+ Link<impl::SeriesHeaderEdit&,void> aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged ));
+
+ for (auto const& elemHeader : aHeaders)
+ {
+ auto spHeader = std::make_shared<impl::SeriesHeader>( m_pColumnsWin, m_pColorsWin );
+ Color nColor;
+ if( elemHeader.m_xDataSeries.is() &&
+ ( elemHeader.m_xDataSeries->getPropertyValue( "Color" ) >>= nColor ))
+ spHeader->SetColor( nColor );
+ spHeader->SetChartType( elemHeader.m_xChartType, elemHeader.m_bSwapXAndYAxis );
+ spHeader->SetSeriesName(
+ elemHeader.m_xDataSeries->getLabelForRole(
+ elemHeader.m_xChartType.is() ?
+ elemHeader.m_xChartType->getRoleOfSequenceForSeriesLabel() :
+ OUString( "values-y")));
+ spHeader->SetRange( elemHeader.m_nStartColumn + 1, elemHeader.m_nEndColumn + 1 );
+ spHeader->SetGetFocusHdl( aFocusLink );
+ spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink );
+ m_aSeriesHeaders.push_back( spHeader );
+ }
+
+ ImplAdjustHeaderControls();
+}
+
+void DataBrowser::ImplAdjustHeaderControls()
+{
+ sal_uInt16 nColCount = GetColumnCount();
+ sal_uInt32 nCurrentPos = GetPosPixel().getX();
+ sal_uInt32 nMaxPos = nCurrentPos + GetOutputSizePixel().getWidth();
+ sal_uInt32 nStartPos = nCurrentPos;
+
+ // width of header column
+ nCurrentPos += GetColumnWidth( 0 );
+
+ weld::Container* pWin = m_pColumnsWin;
+ weld::Container* pColorWin = m_pColorsWin;
+ pWin->set_margin_start(nCurrentPos);
+ pColorWin->set_margin_start(nCurrentPos);
+
+ tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin());
+ sal_uInt16 i = GetFirstVisibleColNumber();
+ while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) )
+ {
+ (*aIt)->Hide();
+ ++aIt;
+ }
+ for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i )
+ {
+ if( (*aIt)->GetStartColumn() == i )
+ nStartPos = nCurrentPos;
+
+ nCurrentPos += (GetColumnWidth( i ));
+
+ if( (*aIt)->GetEndColumn() == i )
+ {
+ if( nStartPos < nMaxPos )
+ {
+ (*aIt)->SetPixelWidth( nCurrentPos - nStartPos );
+ (*aIt)->Show();
+
+ if (pWin)
+ {
+ pWin->set_margin_start(nStartPos);
+ pColorWin->set_margin_start(nStartPos);
+ pWin = pColorWin = nullptr;
+ }
+
+ }
+ else
+ (*aIt)->Hide();
+ ++aIt;
+ }
+ }
+}
+
+IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit&, rEdit, void )
+{
+ rEdit.SetShowWarningBox( !m_bDataValid );
+
+ if( !m_bDataValid )
+ GoToCell( 0, 0 );
+ else
+ {
+ MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( rEdit.getStartColumn()) );
+ ActivateCell();
+ m_aCursorMovedHdlLink.Call( this );
+ }
+}
+
+IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit&, rEdit, void )
+{
+ rtl::Reference< DataSeries > xSeries =
+ m_apDataBrowserModel->getDataSeriesByColumn( rEdit.getStartColumn() - 1 );
+ if( !xSeries.is())
+ return;
+
+ rtl::Reference< ChartType > xChartType(
+ m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType );
+ if( xChartType.is())
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq =
+ DataSeriesHelper::getDataSequenceByRole( xSeries, xChartType->getRoleOfSequenceForSeriesLabel());
+ if( xLabeledSeq.is())
+ {
+ Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY );
+ if( xIndexReplace.is())
+ xIndexReplace->replaceByIndex(
+ 0, uno::Any( rEdit.GetText()));
+ }
+ }
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DataBrowser.hxx b/chart2/source/controller/dialogs/DataBrowser.hxx
new file mode 100644
index 0000000000..c1d6a72e6c
--- /dev/null
+++ b/chart2/source/controller/dialogs/DataBrowser.hxx
@@ -0,0 +1,187 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <svtools/editbrowsebox.hxx>
+#include <vcl/weld.hxx>
+
+#include <memory>
+#include <vector>
+
+namespace com::sun::star {
+ namespace awt {
+ class XWindow;
+ }
+ namespace chart2 {
+ class XChartDocument;
+ }
+}
+
+namespace com::sun::star::uno { class XComponentContext; }
+
+class OutputDevice;
+
+namespace chart
+{
+
+class DataBrowserModel;
+class NumberFormatterWrapper;
+class ChartModel;
+
+namespace impl
+{
+class SeriesHeader;
+class SeriesHeaderEdit;
+}
+
+class DataBrowser : public ::svt::EditBrowseBox
+{
+protected:
+ // EditBrowseBox overridables
+ virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const override;
+ virtual bool SeekRow( sal_Int32 nRow ) override;
+ virtual bool IsTabAllowed( bool bForward ) const override;
+ virtual ::svt::CellController* GetController( sal_Int32 nRow, sal_uInt16 nCol ) override;
+ virtual void InitController( ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol ) override;
+ virtual bool SaveModified() override;
+ virtual void CursorMoved() override;
+ // called whenever the control of the current cell has been modified
+ virtual void CellModified() override;
+ virtual void ColumnResized( sal_uInt16 nColId ) override;
+ virtual void EndScroll() override;
+ virtual void MouseButtonDown( const BrowserMouseEvent& rEvt ) override;
+
+public:
+ DataBrowser(const css::uno::Reference<css::awt::XWindow> &rParent,
+ weld::Container* pColumns, weld::Container* pColors);
+
+ virtual ~DataBrowser() override;
+ virtual void dispose() override;
+
+ /** GetCellText returns the text at the given position
+ @param nRow
+ the number of the row
+ @param nColId
+ the ID of the column
+ @return
+ the text out of the cell
+ */
+ virtual OUString GetCellText(sal_Int32 nRow, sal_uInt16 nColId) const override;
+
+ /** returns the number in the given cell. If a cell is empty or contains a
+ string, the result will be Nan
+ */
+ double GetCellNumber( sal_Int32 nRow, sal_uInt16 nColumnId ) const;
+
+ bool isDateTimeString( const OUString& aInputString, double& fOutDateTimeValue );
+
+ // Window
+ virtual void Resize() override;
+
+ void SetReadOnly( bool bNewState );
+ bool IsReadOnly() const { return m_bIsReadOnly;}
+
+ void SetDataFromModel( const rtl::Reference<::chart::ChartModel> & xChartDoc );
+
+ // predicates to determine what actions are possible at the current cursor
+ // position. This depends on the implementation of the according mutators
+ // below. (They are used for enabling toolbar icons)
+ bool MayInsertRow() const;
+ bool MayInsertColumn() const;
+ bool MayDeleteRow() const;
+ bool MayDeleteColumn() const;
+
+ bool MayMoveUpRows() const;
+ bool MayMoveDownRows() const;
+ bool MayMoveRightColumns() const;
+ bool MayMoveLeftColumns() const;
+
+ // mutators mutating data
+ void InsertRow();
+ void InsertColumn();
+ void InsertTextColumn();
+ void RemoveRow();
+ void RemoveColumn();
+
+ using BrowseBox::RemoveColumn;
+ using BrowseBox::MouseButtonDown;
+
+ void MoveUpRow();
+ void MoveDownRow();
+ void MoveLeftColumn();
+ void MoveRightColumn();
+
+ void SetCursorMovedHdl( const Link<DataBrowser*,void>& rLink );
+
+ /// confirms all pending changes to be ready to be closed
+ bool EndEditing();
+
+ bool CellContainsNumbers( sal_uInt16 nCol ) const;
+
+ sal_uInt32 GetNumberFormatKey( sal_uInt16 nCol ) const;
+
+ bool IsEnableItem() const { return m_bDataValid;}
+ bool IsDataValid() const;
+ void ShowWarningBox();
+ bool ShowQueryBox();
+
+ void RenewSeriesHeaders();
+
+private:
+ rtl::Reference<::chart::ChartModel> m_xChartDoc;
+ std::unique_ptr< DataBrowserModel > m_apDataBrowserModel;
+
+ typedef std::vector< std::shared_ptr< impl::SeriesHeader > > tSeriesHeaderContainer;
+ tSeriesHeaderContainer m_aSeriesHeaders;
+
+ std::shared_ptr< NumberFormatterWrapper > m_spNumberFormatterWrapper;
+
+ /// the row that is currently painted
+ sal_Int32 m_nSeekRow;
+ bool m_bIsReadOnly;
+ bool m_bDataValid;
+
+ VclPtr<svt::FormattedControl> m_aNumberEditField;
+ VclPtr<svt::EditControl> m_aTextEditField;
+ weld::Container* m_pColumnsWin;
+ weld::Container* m_pColorsWin;
+
+ /// note: m_aNumberEditField must precede this member!
+ ::svt::CellControllerRef m_rNumberEditController;
+ /// note: m_aTextEditField must precede this member!
+ ::svt::CellControllerRef m_rTextEditController;
+
+ Link<DataBrowser*,void> m_aCursorMovedHdlLink;
+
+ void clearHeaders();
+ void RenewTable();
+ void ImplAdjustHeaderControls();
+
+ OUString GetColString( sal_Int32 nColumnId ) const;
+
+ DECL_LINK( SeriesHeaderGotFocus, impl::SeriesHeaderEdit&, void );
+ DECL_LINK( SeriesHeaderChanged, impl::SeriesHeaderEdit&, void );
+
+ DataBrowser( const DataBrowser & ) = delete;
+};
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DataBrowserModel.cxx b/chart2/source/controller/dialogs/DataBrowserModel.cxx
new file mode 100644
index 0000000000..63ec6f31fc
--- /dev/null
+++ b/chart2/source/controller/dialogs/DataBrowserModel.cxx
@@ -0,0 +1,935 @@
+/* -*- 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 .
+ */
+
+#include "DataBrowserModel.hxx"
+#include "DialogModel.hxx"
+#include <ChartModelHelper.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeManager.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <ControllerLockGuard.hxx>
+#include <StatisticsHelper.hxx>
+#include <ChartTypeHelper.hxx>
+#include <chartview/ExplicitValueProvider.hxx>
+#include <ExplicitCategoriesProvider.hxx>
+#include <BaseCoordinateSystem.hxx>
+#include <ChartModel.hxx>
+#include <unonames.hxx>
+
+#include <com/sun/star/container/XIndexReplace.hpp>
+#include <com/sun/star/chart2/XInternalDataProvider.hpp>
+#include <com/sun/star/chart2/data/XDataSource.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
+#include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
+#include <o3tl/safeint.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <comphelper/property.hxx>
+
+#include <algorithm>
+#include <cstddef>
+#include <limits>
+#include <utility>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+
+namespace chart {
+
+namespace {
+
+OUString lcl_getRole(
+ const Reference< chart2::data::XDataSequence > & xSeq )
+{
+ OUString aResult;
+ Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ try
+ {
+ xProp->getPropertyValue( "Role" ) >>= aResult;
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ return aResult;
+}
+
+OUString lcl_getUIRoleName(
+ const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
+{
+ OUString aResult = DataSeriesHelper::getRole(xLSeq);
+ if( !aResult.isEmpty())
+ aResult = DialogModel::ConvertRoleFromInternalToUI(aResult);
+ return aResult;
+}
+
+void lcl_copyDataSequenceProperties(
+ const Reference< chart2::data::XDataSequence > & xOldSequence,
+ const Reference< chart2::data::XDataSequence > & xNewSequence )
+{
+ Reference< beans::XPropertySet > xOldSeqProp( xOldSequence, uno::UNO_QUERY );
+ Reference< beans::XPropertySet > xNewSeqProp( xNewSequence, uno::UNO_QUERY );
+ comphelper::copyProperties( xOldSeqProp, xNewSeqProp );
+}
+
+bool lcl_SequenceOfSeriesIsShared(
+ const rtl::Reference< ::chart::DataSeries > & xSeries,
+ const Reference< chart2::data::XDataSequence > & xValues )
+{
+ bool bResult = false;
+ if( !xValues.is())
+ return bResult;
+ try
+ {
+ OUString aValuesRole( lcl_getRole( xValues ));
+ OUString aValuesRep( xValues->getSourceRangeRepresentation());
+ const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aLSeq( xSeries->getDataSequences2());
+ for( uno::Reference< chart2::data::XLabeledDataSequence > const & labeledDataSeq : aLSeq )
+ if (labeledDataSeq.is() && DataSeriesHelper::getRole(labeledDataSeq) == aValuesRole)
+ {
+ // getValues().is(), because lcl_getRole checked that already
+ bResult = (aValuesRep == labeledDataSeq->getValues()->getSourceRangeRepresentation());
+ // assumption: a role appears only once in a series
+ break;
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return bResult;
+}
+
+typedef std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > lcl_tSharedSeqVec;
+
+lcl_tSharedSeqVec lcl_getSharedSequences( const std::vector< rtl::Reference< DataSeries > > & rSeries )
+{
+ // @todo: if only some series share a sequence, those have to be duplicated
+ // and made unshared for all series
+ lcl_tSharedSeqVec aResult;
+ // if we have only one series, we don't want any shared sequences
+ if( rSeries.size() <= 1 )
+ return aResult;
+
+ for( uno::Reference< chart2::data::XLabeledDataSequence > const & labeledDataSeq : rSeries[0]->getDataSequences2() )
+ {
+ Reference< chart2::data::XDataSequence > xValues( labeledDataSeq->getValues());
+ bool bShared = true;
+ for( std::size_t nSeriesIdx=1; nSeriesIdx<rSeries.size(); ++nSeriesIdx )
+ {
+ bShared = lcl_SequenceOfSeriesIsShared( rSeries[nSeriesIdx], xValues );
+ if( !bShared )
+ break;
+ }
+ if( bShared )
+ aResult.push_back( labeledDataSeq );
+ }
+
+ return aResult;
+}
+
+sal_Int32 lcl_getValuesRepresentationIndex(
+ const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
+{
+ sal_Int32 nResult = -1;
+ if( xLSeq.is())
+ {
+ Reference< chart2::data::XDataSequence > xSeq( xLSeq->getValues());
+ if( xSeq.is())
+ {
+ OUString aRep( xSeq->getSourceRangeRepresentation());
+ nResult = aRep.toInt32();
+ }
+ }
+ return nResult;
+}
+
+struct lcl_RepresentationsOfLSeqMatch
+{
+ explicit lcl_RepresentationsOfLSeqMatch( const Reference< chart2::data::XLabeledDataSequence > & xLSeq ) :
+ m_aValuesRep( xLSeq.is() ?
+ (xLSeq->getValues().is() ? xLSeq->getValues()->getSourceRangeRepresentation() : OUString())
+ : OUString() )
+ {}
+ bool operator() ( const Reference< chart2::data::XLabeledDataSequence > & xLSeq )
+ {
+ if (!xLSeq.is() || !xLSeq->getValues().is())
+ return false;
+
+ return xLSeq->getValues()->getSourceRangeRepresentation() == m_aValuesRep;
+ }
+private:
+ OUString m_aValuesRep;
+};
+
+struct lcl_RolesOfLSeqMatch
+{
+ explicit lcl_RolesOfLSeqMatch( const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq ) :
+ m_aRole(DataSeriesHelper::getRole(xLSeq)) {}
+
+ bool operator() ( const uno::Reference< chart2::data::XLabeledDataSequence > & xLSeq )
+ {
+ return DataSeriesHelper::getRole(xLSeq) == m_aRole;
+ }
+private:
+ OUString m_aRole;
+};
+
+bool lcl_ShowCategoriesAsDataLabel( const rtl::Reference< ::chart::Diagram > & xDiagram )
+{
+ return !xDiagram->isCategory();
+}
+
+} // anonymous namespace
+
+struct DataBrowserModel::tDataColumn
+{
+ rtl::Reference<DataSeries> m_xDataSeries;
+ OUString m_aUIRoleName;
+ uno::Reference<chart2::data::XLabeledDataSequence> m_xLabeledDataSequence;
+ eCellType m_eCellType;
+ sal_Int32 m_nNumberFormatKey;
+
+ // default CTOR
+ tDataColumn() : m_eCellType( TEXT ), m_nNumberFormatKey( 0 ) {}
+ // "full" CTOR
+ tDataColumn(
+ rtl::Reference<DataSeries> xDataSeries,
+ OUString aUIRoleName,
+ uno::Reference<chart2::data::XLabeledDataSequence> xLabeledDataSequence,
+ eCellType aCellType,
+ sal_Int32 nNumberFormatKey ) :
+ m_xDataSeries(std::move( xDataSeries )),
+ m_aUIRoleName(std::move( aUIRoleName )),
+ m_xLabeledDataSequence(std::move( xLabeledDataSequence )),
+ m_eCellType( aCellType ),
+ m_nNumberFormatKey( nNumberFormatKey )
+ {}
+};
+
+struct DataBrowserModel::implColumnLess
+{
+ bool operator() ( const DataBrowserModel::tDataColumn & rLeft, const DataBrowserModel::tDataColumn & rRight )
+ {
+ if( rLeft.m_xLabeledDataSequence.is() && rRight.m_xLabeledDataSequence.is())
+ {
+ return DialogModel::GetRoleIndexForSorting(DataSeriesHelper::getRole(rLeft.m_xLabeledDataSequence)) <
+ DialogModel::GetRoleIndexForSorting(DataSeriesHelper::getRole(rRight.m_xLabeledDataSequence));
+ }
+ return true;
+ }
+};
+
+DataBrowserModel::DataBrowserModel(
+ const rtl::Reference<::chart::ChartModel> & xChartDoc ) :
+ m_xChartDocument( xChartDoc ),
+ m_apDialogModel( new DialogModel( xChartDoc ))
+{
+ updateFromModel();
+}
+
+DataBrowserModel::~DataBrowserModel()
+{}
+
+namespace
+{
+struct lcl_DataSeriesOfHeaderMatches
+{
+ explicit lcl_DataSeriesOfHeaderMatches(
+ rtl::Reference< ::chart::DataSeries > xSeriesToCompareWith ) :
+ m_xSeries(std::move( xSeriesToCompareWith ))
+ {}
+ bool operator() ( const ::chart::DataBrowserModel::tDataHeader & rHeader )
+ {
+ return (m_xSeries == rHeader.m_xDataSeries);
+ }
+private:
+ rtl::Reference< ::chart::DataSeries > m_xSeries;
+};
+}
+
+void DataBrowserModel::insertDataSeries( sal_Int32 nAfterColumnIndex )
+{
+ OSL_ASSERT(m_apDialogModel);
+ Reference< chart2::XInternalDataProvider > xDataProvider(
+ m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+
+ if (!xDataProvider.is())
+ return;
+
+ if( isCategoriesColumn(nAfterColumnIndex) )
+ // Move to the last category column.
+ nAfterColumnIndex = getCategoryColumnCount()-1;
+
+ sal_Int32 nStartCol = 0;
+ rtl::Reference< Diagram > xDiagram = m_xChartDocument->getFirstChartDiagram();
+ rtl::Reference<ChartType> xChartType;
+ rtl::Reference<DataSeries> xSeries;
+ if (o3tl::make_unsigned(nAfterColumnIndex) < m_aColumns.size())
+ // Get the data series at specific column position (if available).
+ xSeries = m_aColumns[nAfterColumnIndex].m_xDataSeries;
+
+ sal_Int32 nSeriesNumberFormat = 0;
+ if( xSeries.is())
+ {
+ // Use the chart type of the currently selected data series.
+ xChartType = xDiagram->getChartTypeOfSeries( xSeries );
+
+ // Find the corresponding header and determine the last column of this
+ // data series.
+ tDataHeaderVector::const_iterator aIt(
+ std::find_if( m_aHeaders.begin(), m_aHeaders.end(),
+ lcl_DataSeriesOfHeaderMatches( xSeries )));
+ if( aIt != m_aHeaders.end())
+ nStartCol = aIt->m_nEndColumn;
+
+ // Get the number format too.
+ if( xSeries.is() )
+ xSeries->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nSeriesNumberFormat;
+ }
+ else
+ {
+ // No data series at specified column position. Use the first chart type.
+ xChartType = xDiagram->getChartTypeByIndex( 0 );
+ nStartCol = nAfterColumnIndex;
+ }
+
+ if (!xChartType.is())
+ return;
+
+ // Get shared sequences of current series. Normally multiple data series
+ // only share "values-x" sequences. (TODO: simplify this logic).
+ lcl_tSharedSeqVec aSharedSequences = lcl_getSharedSequences( xChartType->getDataSeries2());
+
+ rtl::Reference<::chart::DataSeries> xNewSeries =
+ m_apDialogModel->insertSeriesAfter(xSeries, xChartType, true);
+
+ if (!xNewSeries.is())
+ // Failed to insert new data series to the model. Bail out.
+ return;
+
+ const std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > & aLSequences = xNewSeries->getDataSequences2();
+ sal_Int32 nSeqIdx = 0;
+ sal_Int32 nSeqSize = aLSequences.size();
+ for (sal_Int32 nIndex = nStartCol; nSeqIdx < nSeqSize; ++nSeqIdx)
+ {
+ lcl_tSharedSeqVec::const_iterator aSharedIt(
+ std::find_if( aSharedSequences.begin(), aSharedSequences.end(),
+ lcl_RolesOfLSeqMatch( aLSequences[nSeqIdx] )));
+
+ if( aSharedIt != aSharedSequences.end())
+ {
+ // Shared sequence. Most likely "values-x" sequence. Copy it from existing sequence.
+ aLSequences[nSeqIdx]->setValues( (*aSharedIt)->getValues());
+ aLSequences[nSeqIdx]->setLabel( (*aSharedIt)->getLabel());
+ }
+ else
+ {
+ // Insert a new column in the internal data for the new sequence.
+ xDataProvider->insertSequence( nIndex - 1 );
+
+ // values
+ Reference< chart2::data::XDataSequence > xNewSeq(
+ xDataProvider->createDataSequenceByRangeRepresentation(
+ OUString::number( nIndex )));
+ lcl_copyDataSequenceProperties(
+ aLSequences[nSeqIdx]->getValues(), xNewSeq );
+ aLSequences[nSeqIdx]->setValues( xNewSeq );
+
+ // labels
+ Reference< chart2::data::XDataSequence > xNewLabelSeq(
+ xDataProvider->createDataSequenceByRangeRepresentation(
+ "label " +
+ OUString::number( nIndex )));
+ lcl_copyDataSequenceProperties(
+ aLSequences[nSeqIdx]->getLabel(), xNewLabelSeq );
+ aLSequences[nSeqIdx]->setLabel( xNewLabelSeq );
+ ++nIndex;
+ }
+ }
+
+ if( nSeriesNumberFormat != 0 )
+ {
+ //give the new series the same number format as the former series especially for bubble charts thus the bubble size values can be edited with same format immediately
+ xNewSeries->setPropertyValue(CHART_UNONAME_NUMFMT , uno::Any(nSeriesNumberFormat));
+ }
+
+ updateFromModel();
+}
+
+void DataBrowserModel::insertComplexCategoryLevel( sal_Int32 nAfterColumnIndex )
+{
+ //create a new text column for complex categories
+
+ OSL_ASSERT(m_apDialogModel);
+ Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ if (!xDataProvider.is())
+ return;
+
+ if( !isCategoriesColumn(nAfterColumnIndex) )
+ nAfterColumnIndex = getCategoryColumnCount()-1;
+
+ if(nAfterColumnIndex<0)
+ {
+ OSL_FAIL( "wrong index for category level insertion" );
+ return;
+ }
+
+ m_apDialogModel->startControllerLockTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+ xDataProvider->insertComplexCategoryLevel( nAfterColumnIndex+1 );
+ updateFromModel();
+}
+
+void DataBrowserModel::removeComplexCategoryLevel( sal_Int32 nAtColumnIndex )
+{
+ //delete a category column if there is more than one level (in case of a single column we do not get here)
+ OSL_ENSURE(nAtColumnIndex>0, "wrong index for categories deletion" );
+
+ Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ if (!xDataProvider.is())
+ return;
+
+ m_apDialogModel->startControllerLockTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+ xDataProvider->deleteComplexCategoryLevel( nAtColumnIndex );
+
+ updateFromModel();
+}
+
+void DataBrowserModel::removeDataSeriesOrComplexCategoryLevel( sal_Int32 nAtColumnIndex )
+{
+ OSL_ASSERT(m_apDialogModel);
+ if (nAtColumnIndex < 0 || o3tl::make_unsigned(nAtColumnIndex) >= m_aColumns.size())
+ // Out of bound.
+ return;
+
+ if (isCategoriesColumn(nAtColumnIndex))
+ {
+ removeComplexCategoryLevel(nAtColumnIndex);
+ return;
+ }
+
+ const rtl::Reference<DataSeries>& xSeries = m_aColumns[nAtColumnIndex].m_xDataSeries;
+
+ m_apDialogModel->deleteSeries(xSeries, getHeaderForSeries(xSeries).m_xChartType);
+
+ //delete sequences from internal data provider that are not used anymore
+ //but do not delete sequences that are still in use by the remaining series
+
+ Reference< chart2::XInternalDataProvider > xDataProvider( m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ if (!xDataProvider.is() || !xSeries.is())
+ {
+ // Something went wrong. Bail out.
+ updateFromModel();
+ return;
+ }
+
+ rtl::Reference<ChartType> xSeriesCnt(getHeaderForSeries(xSeries).m_xChartType);
+ if (!xSeriesCnt.is())
+ {
+ // Unexpected happened. Bail out.
+ updateFromModel();
+ return;
+ }
+
+ // Collect all the remaining data sequences in the same chart type. The
+ // deleted data series is already gone by this point.
+ std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > aAllDataSeqs =
+ DataSeriesHelper::getAllDataSequences(xSeriesCnt->getDataSeries2());
+
+ // Check if the sequences to be deleted are still referenced by any of
+ // the other data series. If not, mark them for deletion.
+ std::vector<sal_Int32> aSequenceIndexesToDelete;
+ const std::vector<uno::Reference<chart2::data::XLabeledDataSequence> > & aSequencesOfDeleted = xSeries->getDataSequences2();
+ for (auto const & labeledDataSeq : aSequencesOfDeleted)
+ {
+ // if not used by the remaining series this sequence can be deleted
+ if( std::none_of( aAllDataSeqs.begin(), aAllDataSeqs.end(),
+ lcl_RepresentationsOfLSeqMatch( labeledDataSeq )) )
+ aSequenceIndexesToDelete.push_back( lcl_getValuesRepresentationIndex( labeledDataSeq ) );
+ }
+
+ // delete unnecessary sequences of the internal data
+ // iterate using greatest index first, so that deletion does not
+ // shift other sequences that will be deleted later
+ std::sort( aSequenceIndexesToDelete.begin(), aSequenceIndexesToDelete.end());
+ for( std::vector< sal_Int32 >::reverse_iterator aIt(
+ aSequenceIndexesToDelete.rbegin()); aIt != aSequenceIndexesToDelete.rend(); ++aIt )
+ {
+ if( *aIt != -1 )
+ xDataProvider->deleteSequence( *aIt );
+ }
+
+ updateFromModel();
+}
+
+void DataBrowserModel::swapDataSeries( sal_Int32 nFirstColumnIndex )
+{
+ OSL_ASSERT(m_apDialogModel);
+ if( o3tl::make_unsigned( nFirstColumnIndex ) < m_aColumns.size() - 1 )
+ {
+ rtl::Reference< DataSeries > xSeries( m_aColumns[nFirstColumnIndex].m_xDataSeries );
+ if( xSeries.is())
+ {
+ m_apDialogModel->moveSeries( xSeries, DialogModel::MoveDirection::Down );
+ updateFromModel();
+ }
+ }
+}
+
+void DataBrowserModel::swapDataPointForAllSeries( sal_Int32 nFirstIndex )
+{
+ OSL_ASSERT(m_apDialogModel);
+ Reference< chart2::XInternalDataProvider > xDataProvider(
+ m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ // lockControllers
+ ControllerLockGuardUNO aGuard( m_apDialogModel->getChartModel());
+ if( xDataProvider.is())
+ xDataProvider->swapDataPointWithNextOneForAllSequences( nFirstIndex );
+ // unlockControllers
+}
+
+void DataBrowserModel::insertDataPointForAllSeries( sal_Int32 nAfterIndex )
+{
+ Reference< chart2::XInternalDataProvider > xDataProvider(
+ m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ // lockControllers
+ ControllerLockGuardUNO aGuard( m_apDialogModel->getChartModel());
+ if( xDataProvider.is())
+ xDataProvider->insertDataPointForAllSequences( nAfterIndex );
+ // unlockControllers
+}
+
+void DataBrowserModel::removeDataPointForAllSeries( sal_Int32 nAtIndex )
+{
+ Reference< chart2::XInternalDataProvider > xDataProvider(
+ m_apDialogModel->getDataProvider(), uno::UNO_QUERY );
+ // lockControllers
+ ControllerLockGuardUNO aGuard( m_apDialogModel->getChartModel());
+ if( xDataProvider.is())
+ xDataProvider->deleteDataPointForAllSequences( nAtIndex );
+ // unlockControllers
+}
+
+DataBrowserModel::tDataHeader DataBrowserModel::getHeaderForSeries(
+ const Reference< chart2::XDataSeries > & xSeries ) const
+{
+ rtl::Reference<DataSeries> pSeries = dynamic_cast<DataSeries*>(xSeries.get());
+ assert(!xSeries || pSeries);
+ for (auto const& elemHeader : m_aHeaders)
+ {
+ if( elemHeader.m_xDataSeries == pSeries )
+ return elemHeader;
+ }
+ return tDataHeader();
+}
+
+rtl::Reference< DataSeries >
+ DataBrowserModel::getDataSeriesByColumn( sal_Int32 nColumn ) const
+{
+ tDataColumnVector::size_type nIndex( nColumn );
+ if( nIndex < m_aColumns.size())
+ return m_aColumns[nIndex].m_xDataSeries;
+ return nullptr;
+}
+
+DataBrowserModel::eCellType DataBrowserModel::getCellType( sal_Int32 nAtColumn ) const
+{
+ eCellType eResult = TEXT;
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size())
+ eResult = m_aColumns[nIndex].m_eCellType;
+ return eResult;
+}
+
+double DataBrowserModel::getCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow )
+{
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size() &&
+ m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
+ {
+ Reference< chart2::data::XNumericalDataSequence > xData(
+ m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY );
+ if( xData.is())
+ {
+ Sequence< double > aValues( xData->getNumericalData());
+ if( nAtRow < aValues.getLength())
+ return aValues[nAtRow];
+ }
+ }
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+uno::Any DataBrowserModel::getCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow )
+{
+ uno::Any aResult;
+
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size() &&
+ m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
+ {
+ Reference< chart2::data::XDataSequence > xData(
+ m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues() );
+ if( xData.is() )
+ {
+ Sequence< uno::Any > aValues( xData->getData());
+ if( nAtRow < aValues.getLength())
+ aResult = aValues[nAtRow];
+ }
+ }
+ return aResult;
+}
+
+OUString DataBrowserModel::getCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow )
+{
+ OUString aResult;
+
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size() &&
+ m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
+ {
+ Reference< chart2::data::XTextualDataSequence > xData(
+ m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY );
+ if( xData.is())
+ {
+ Sequence< OUString > aValues( xData->getTextualData());
+ if( nAtRow < aValues.getLength())
+ aResult = aValues[nAtRow];
+ }
+ }
+ return aResult;
+}
+
+sal_uInt32 DataBrowserModel::getNumberFormatKey( sal_Int32 nAtColumn )
+{
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size())
+ return m_aColumns[ nIndex ].m_nNumberFormatKey;
+ return 0;
+}
+
+bool DataBrowserModel::setCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow, const uno::Any & rValue )
+{
+ bool bResult = false;
+ tDataColumnVector::size_type nIndex( nAtColumn );
+ if( nIndex < m_aColumns.size() &&
+ m_aColumns[ nIndex ].m_xLabeledDataSequence.is())
+ {
+ bResult = true;
+ try
+ {
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+
+ // label
+ if( nAtRow == -1 )
+ {
+ Reference< container::XIndexReplace > xIndexReplace(
+ m_aColumns[ nIndex ].m_xLabeledDataSequence->getLabel(), uno::UNO_QUERY_THROW );
+ xIndexReplace->replaceByIndex( 0, rValue );
+ }
+ else
+ {
+ Reference< container::XIndexReplace > xIndexReplace(
+ m_aColumns[ nIndex ].m_xLabeledDataSequence->getValues(), uno::UNO_QUERY_THROW );
+ xIndexReplace->replaceByIndex( nAtRow, rValue );
+ }
+
+ m_apDialogModel->startControllerLockTimer();
+ //notify change directly to the model (this is necessary here as sequences for complex categories not known directly to the chart model so they do not notify their changes) (for complex categories see issue #i82971#)
+ if( m_xChartDocument.is() )
+ m_xChartDocument->setModified(true);
+ }
+ catch( const uno::Exception & )
+ {
+ bResult = false;
+ }
+ }
+ return bResult;
+}
+
+bool DataBrowserModel::setCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow, double fValue )
+{
+ return (getCellType( nAtColumn ) == NUMBER) &&
+ setCellAny( nAtColumn, nAtRow, uno::Any( fValue ));
+}
+
+bool DataBrowserModel::setCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow, const OUString & rText )
+{
+ return (getCellType( nAtColumn ) == TEXT) &&
+ setCellAny( nAtColumn, nAtRow, uno::Any( rText ));
+}
+
+sal_Int32 DataBrowserModel::getColumnCount() const
+{
+ return static_cast< sal_Int32 >( m_aColumns.size());
+}
+
+sal_Int32 DataBrowserModel::getMaxRowCount() const
+{
+ sal_Int32 nResult = 0;
+ for (auto const& column : m_aColumns)
+ {
+ if( column.m_xLabeledDataSequence.is())
+ {
+ Reference< chart2::data::XDataSequence > xSeq(
+ column.m_xLabeledDataSequence->getValues());
+ if( !xSeq.is())
+ continue;
+ sal_Int32 nLength( xSeq->getData().getLength());
+ if( nLength > nResult )
+ nResult = nLength;
+ }
+ }
+
+ return nResult;
+}
+
+OUString DataBrowserModel::getRoleOfColumn( sal_Int32 nColumnIndex ) const
+{
+ if( nColumnIndex != -1 &&
+ o3tl::make_unsigned( nColumnIndex ) < m_aColumns.size())
+ return m_aColumns[ nColumnIndex ].m_aUIRoleName;
+ return OUString();
+}
+
+bool DataBrowserModel::isCategoriesColumn( sal_Int32 nColumnIndex ) const
+{
+ if (nColumnIndex < 0)
+ return false;
+
+ if (o3tl::make_unsigned(nColumnIndex) >= m_aColumns.size())
+ return false;
+
+ // A column is a category when it doesn't have an associated data series.
+ return !m_aColumns[nColumnIndex].m_xDataSeries.is();
+}
+
+sal_Int32 DataBrowserModel::getCategoryColumnCount()
+{
+ sal_Int32 nLastTextColumnIndex = -1;
+ for (auto const& column : m_aColumns)
+ {
+ if( !column.m_xDataSeries.is() )
+ nLastTextColumnIndex++;
+ else
+ break;
+ }
+ return nLastTextColumnIndex+1;
+}
+
+void DataBrowserModel::updateFromModel()
+{
+ if( !m_xChartDocument.is())
+ return;
+ m_aColumns.clear();
+ m_aHeaders.clear();
+
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
+ if( !xDiagram.is())
+ return;
+
+ // set template at DialogModel
+ rtl::Reference< ::chart::ChartTypeManager > xChartTypeManager = m_xChartDocument->getTypeManager();
+ Diagram::tTemplateWithServiceName aTemplateAndService =
+ xDiagram->getTemplate( xChartTypeManager );
+ if( aTemplateAndService.xChartTypeTemplate.is())
+ m_apDialogModel->setTemplate( aTemplateAndService.xChartTypeTemplate );
+
+ sal_Int32 nHeaderStart = 0;
+ sal_Int32 nHeaderEnd = 0;
+ {
+ ExplicitCategoriesProvider aExplicitCategoriesProvider( ChartModelHelper::getFirstCoordinateSystem(m_xChartDocument), *m_xChartDocument );
+
+ const std::vector< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList = aExplicitCategoriesProvider.getSplitCategoriesList();
+ sal_Int32 nLevelCount = rSplitCategoriesList.size();
+ for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
+ {
+ Reference< chart2::data::XLabeledDataSequence > xCategories( rSplitCategoriesList[nL] );
+ if( !xCategories.is() )
+ continue;
+
+ tDataColumn aCategories;
+ aCategories.m_xLabeledDataSequence = xCategories;
+ if( lcl_ShowCategoriesAsDataLabel( xDiagram ))
+ aCategories.m_aUIRoleName = DialogModel::GetRoleDataLabel();
+ else
+ aCategories.m_aUIRoleName = lcl_getUIRoleName( xCategories );
+ aCategories.m_eCellType = TEXTORDATE;
+ m_aColumns.push_back( aCategories );
+ ++nHeaderStart;
+ }
+ }
+
+ if( !xDiagram.is())
+ return;
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysSeq( xDiagram->getBaseCoordinateSystems());
+ for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq )
+ {
+ const std::vector< rtl::Reference< ChartType > > aChartTypes( coords->getChartTypes2());
+ sal_Int32 nXAxisNumberFormat = DataSeriesHelper::getNumberFormatKeyFromAxis( nullptr, coords, 0, 0 );
+
+ for( auto const & CT: aChartTypes )
+ {
+ rtl::Reference< ChartType > xSeriesCnt( CT );
+ OUString aRoleForDataLabelNumberFormat = ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( CT );
+
+ const std::vector< rtl::Reference< DataSeries > > & aSeries( xSeriesCnt->getDataSeries2());
+ lcl_tSharedSeqVec aSharedSequences( lcl_getSharedSequences( aSeries ));
+ for (auto const& sharedSequence : aSharedSequences)
+ {
+ tDataColumn aSharedSequence;
+ aSharedSequence.m_xLabeledDataSequence = sharedSequence;
+ aSharedSequence.m_aUIRoleName = lcl_getUIRoleName(sharedSequence);
+ aSharedSequence.m_eCellType = NUMBER;
+ // as the sequences are shared it should be ok to take the first series
+ // @todo: dimension index 0 for x-values used here. This is just a guess.
+ // Also, the axis index is 0, as there is usually only one x-axis
+ aSharedSequence.m_nNumberFormatKey = nXAxisNumberFormat;
+ m_aColumns.push_back( aSharedSequence );
+ ++nHeaderStart;
+ }
+ for( rtl::Reference< DataSeries > const & dataSeries : aSeries )
+ {
+ tDataColumnVector::size_type nStartColIndex = m_aColumns.size();
+ rtl::Reference< DataSeries > xSeries( dataSeries );
+ if( xSeries.is())
+ {
+ const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aLSeqs( xSeries->getDataSequences2());
+ if( aLSeqs.empty() )
+ continue;
+ nHeaderEnd = nHeaderStart;
+
+ // @todo: dimension index 1 for y-values used here. This is just a guess
+ sal_Int32 nYAxisNumberFormatKey =
+ DataSeriesHelper::getNumberFormatKeyFromAxis(
+ dataSeries, coords, 1 );
+
+ sal_Int32 nSeqIdx=0;
+ for( ; nSeqIdx<static_cast<sal_Int32>(aLSeqs.size()); ++nSeqIdx )
+ {
+ sal_Int32 nSequenceNumberFormatKey = nYAxisNumberFormatKey;
+ OUString aRole = DataSeriesHelper::getRole(aLSeqs[nSeqIdx]);
+
+ if( aRole == aRoleForDataLabelNumberFormat )
+ {
+ nSequenceNumberFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
+ xSeries);
+ }
+ else if( aRole == "values-x" )
+ nSequenceNumberFormatKey = nXAxisNumberFormat;
+
+ if( std::none_of( aSharedSequences.begin(), aSharedSequences.end(),
+ lcl_RepresentationsOfLSeqMatch( aLSeqs[nSeqIdx] )) )
+ {
+ // no shared sequence
+ m_aColumns.emplace_back(
+ dataSeries,
+ lcl_getUIRoleName( aLSeqs[nSeqIdx] ),
+ aLSeqs[nSeqIdx],
+ NUMBER,
+ nSequenceNumberFormatKey );
+ ++nHeaderEnd;
+ }
+ // else skip
+ }
+ bool bSwapXAndYAxis = false;
+ try
+ {
+ coords->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXAndYAxis;
+ }
+ catch( const beans::UnknownPropertyException & ) {}
+
+ // add ranges for error bars if present for a series
+ if( StatisticsHelper::usesErrorBarRanges( dataSeries ))
+ addErrorBarRanges( dataSeries, nYAxisNumberFormatKey, nSeqIdx, nHeaderEnd, true );
+
+ if( StatisticsHelper::usesErrorBarRanges( dataSeries, /* bYError = */ false ))
+ addErrorBarRanges( dataSeries, nYAxisNumberFormatKey, nSeqIdx, nHeaderEnd, false );
+
+ m_aHeaders.emplace_back(
+ dataSeries,
+ CT,
+ bSwapXAndYAxis,
+ nHeaderStart,
+ nHeaderEnd - 1 );
+
+ nHeaderStart = nHeaderEnd;
+
+ std::sort( m_aColumns.begin() + nStartColIndex, m_aColumns.end(), implColumnLess() );
+ }
+ }
+ }
+ }
+}
+
+void DataBrowserModel::addErrorBarRanges(
+ const rtl::Reference< DataSeries > & xDataSeries,
+ sal_Int32 nNumberFormatKey,
+ sal_Int32 & rInOutSequenceIndex,
+ sal_Int32 & rInOutHeaderEnd, bool bYError )
+{
+ try
+ {
+ std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences;
+
+ Reference< chart2::data::XDataSource > xErrorSource(
+ StatisticsHelper::getErrorBars( xDataSeries, bYError ), uno::UNO_QUERY );
+
+ uno::Reference< chart2::data::XLabeledDataSequence > xErrorLSequence =
+ StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
+ xErrorSource,
+ /* bPositiveValue = */ true,
+ bYError );
+ if( xErrorLSequence.is())
+ aSequences.push_back( xErrorLSequence );
+
+ xErrorLSequence =
+ StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
+ xErrorSource,
+ /* bPositiveValue = */ false,
+ bYError );
+ if( xErrorLSequence.is())
+ aSequences.push_back( xErrorLSequence );
+
+ for (uno::Reference<chart2::data::XLabeledDataSequence> const & rDataSequence : aSequences)
+ {
+ m_aColumns.emplace_back(xDataSeries, lcl_getUIRoleName(rDataSequence),
+ rDataSequence, NUMBER, nNumberFormatKey);
+ ++rInOutSequenceIndex;
+ ++rInOutHeaderEnd;
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DataBrowserModel.hxx b/chart2/source/controller/dialogs/DataBrowserModel.hxx
new file mode 100644
index 0000000000..e3254851d0
--- /dev/null
+++ b/chart2/source/controller/dialogs/DataBrowserModel.hxx
@@ -0,0 +1,170 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <DataSeries.hxx>
+#include <ChartType.hxx>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ref.hxx>
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace com::sun::star::chart2 { class XChartDocument; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+namespace com::sun::star::chart2 {
+ class XDataSeries;
+ class XChartType;
+}
+
+namespace chart
+{
+
+class DialogModel;
+class ChartModel;
+class ChartType;
+class DataSeries;
+
+class DataBrowserModel final
+{
+public:
+ explicit DataBrowserModel(
+ const rtl::Reference<::chart::ChartModel> & xChartDoc );
+ ~DataBrowserModel();
+
+ /** Inserts a new data series after the data series to which the data column
+ with index nAfterColumnIndex belongs.
+ */
+ void insertDataSeries( sal_Int32 nAfterColumnIndex );
+
+ /** Inserts a new text column for complex categories.
+ */
+ void insertComplexCategoryLevel( sal_Int32 nAfterColumnIndex );
+
+ /** Removes a data series to which the data column with index nAtColumnIndex
+ belongs.
+ */
+ void removeDataSeriesOrComplexCategoryLevel( sal_Int32 nAtColumnIndex );
+
+ /** Swaps the series to which the data column with index nFirstIndex belongs
+ with the next series (which starts at an index >= nFirstIndex + 1)
+ */
+ void swapDataSeries( sal_Int32 nFirstIndex );
+ void swapDataPointForAllSeries( sal_Int32 nFirstIndex );
+
+ void insertDataPointForAllSeries( sal_Int32 nAfterIndex );
+ void removeDataPointForAllSeries( sal_Int32 nAtIndex );
+
+ enum eCellType
+ {
+ NUMBER,
+ TEXT,
+ TEXTORDATE
+ };
+
+ eCellType getCellType( sal_Int32 nAtColumn ) const;
+ /// If getCellType( nAtColumn, nAtRow ) returns TEXT, the result will be Nan
+ double getCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow );
+ OUString getCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow );
+ css::uno::Any getCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow );
+ sal_uInt32 getNumberFormatKey( sal_Int32 nAtColumn );
+
+ /// returns </sal_True> if the number could successfully be set at the given position
+ bool setCellNumber( sal_Int32 nAtColumn, sal_Int32 nAtRow, double fValue );
+ /// returns </sal_True> if the text could successfully be set at the given position
+ bool setCellText( sal_Int32 nAtColumn, sal_Int32 nAtRow, const OUString & rText );
+ bool setCellAny( sal_Int32 nAtColumn, sal_Int32 nAtRow, const css::uno::Any & aValue );
+
+ sal_Int32 getColumnCount() const;
+ sal_Int32 getMaxRowCount() const;
+
+ // returns the UI string of the corresponding role
+ OUString getRoleOfColumn( sal_Int32 nColumnIndex ) const;
+ bool isCategoriesColumn( sal_Int32 nColumnIndex ) const;
+
+ struct tDataHeader
+ {
+ rtl::Reference< ::chart::DataSeries > m_xDataSeries;
+ rtl::Reference< ::chart::ChartType > m_xChartType;
+ bool m_bSwapXAndYAxis;
+ sal_Int32 m_nStartColumn;
+ sal_Int32 m_nEndColumn;
+
+ // default CTOR
+ tDataHeader() :
+ m_bSwapXAndYAxis( false ),
+ m_nStartColumn( -1 ),
+ m_nEndColumn( -1 )
+ {}
+ // "full" CTOR
+ tDataHeader(
+ rtl::Reference< ::chart::DataSeries > xDataSeries,
+ rtl::Reference< ::chart::ChartType > xChartType,
+ bool bSwapXAndYAxis,
+ sal_Int32 nStartColumn,
+ sal_Int32 nEndColumn ) :
+ m_xDataSeries(std::move( xDataSeries )),
+ m_xChartType(std::move( xChartType )),
+ m_bSwapXAndYAxis( bSwapXAndYAxis ),
+ m_nStartColumn( nStartColumn ),
+ m_nEndColumn( nEndColumn )
+ {}
+ };
+
+ typedef std::vector< tDataHeader > tDataHeaderVector;
+
+ const tDataHeaderVector& getDataHeaders() const { return m_aHeaders;}
+
+ tDataHeader getHeaderForSeries(
+ const css::uno::Reference< css::chart2::XDataSeries > &xSeries ) const;
+
+ rtl::Reference< ::chart::DataSeries >
+ getDataSeriesByColumn( sal_Int32 nColumn ) const;
+
+private:
+ void updateFromModel();
+
+ void removeComplexCategoryLevel( sal_Int32 nAtColumnIndex );
+
+ void addErrorBarRanges(
+ const rtl::Reference<::chart::DataSeries > & xDataSeries,
+ sal_Int32 nNumberFormatKey,
+ sal_Int32 & rInOutSequenceIndex,
+ sal_Int32 & rInOutHeaderEnd, bool bYError );
+
+ sal_Int32 getCategoryColumnCount();
+
+ rtl::Reference<::chart::ChartModel> m_xChartDocument;
+ std::unique_ptr< DialogModel > m_apDialogModel;
+
+ struct tDataColumn;
+ struct implColumnLess;
+
+ typedef std::vector< tDataColumn > tDataColumnVector;
+
+ tDataColumnVector m_aColumns;
+ tDataHeaderVector m_aHeaders;
+};
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DialogModel.cxx b/chart2/source/controller/dialogs/DialogModel.cxx
new file mode 100644
index 0000000000..edd00184e6
--- /dev/null
+++ b/chart2/source/controller/dialogs/DialogModel.cxx
@@ -0,0 +1,849 @@
+/* -*- 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 .
+ */
+
+#include "DialogModel.hxx"
+#include <RangeSelectionHelper.hxx>
+#include <DataInterpreter.hxx>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <DataSourceHelper.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <strings.hrc>
+#include <ResId.hxx>
+#include <ControllerLockGuard.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeHelper.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <ThreeDHelper.hxx>
+#include <ChartModel.hxx>
+#include <BaseCoordinateSystem.hxx>
+#include <LabeledDataSequence.hxx>
+
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <utility>
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+#include <numeric>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+
+namespace
+{
+constexpr OUString lcl_aLabelRole( u"label"_ustr );
+
+
+OUString lcl_ConvertRole( const OUString & rRoleString )
+{
+ OUString aResult( rRoleString );
+
+ typedef std::map< OUString, OUString > tTranslationMap;
+ static const tTranslationMap aTranslationMap =
+ {
+ { "categories", ::chart::SchResId( STR_DATA_ROLE_CATEGORIES ) },
+ { "error-bars-x", ::chart::SchResId( STR_DATA_ROLE_X_ERROR ) },
+ { "error-bars-x-positive", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE ) },
+ { "error-bars-x-negative", ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE ) },
+ { "error-bars-y", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR ) },
+ { "error-bars-y-positive", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE ) },
+ { "error-bars-y-negative", ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE ) },
+ { "label", ::chart::SchResId( STR_DATA_ROLE_LABEL ) },
+ { "values-first", ::chart::SchResId( STR_DATA_ROLE_FIRST ) },
+ { "values-last", ::chart::SchResId( STR_DATA_ROLE_LAST ) },
+ { "values-max", ::chart::SchResId( STR_DATA_ROLE_MAX ) },
+ { "values-min", ::chart::SchResId( STR_DATA_ROLE_MIN ) },
+ { "values-x", ::chart::SchResId( STR_DATA_ROLE_X ) },
+ { "values-y", ::chart::SchResId( STR_DATA_ROLE_Y ) },
+ { "values-size", ::chart::SchResId( STR_DATA_ROLE_SIZE ) },
+ { "FillColor", ::chart::SchResId( STR_PROPERTY_ROLE_FILLCOLOR ) },
+ { "BorderColor", ::chart::SchResId( STR_PROPERTY_ROLE_BORDERCOLOR ) },
+ };
+
+ tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString ));
+ if( aIt != aTranslationMap.end())
+ {
+ aResult = (*aIt).second;
+ }
+ return aResult;
+}
+
+typedef std::map< OUString, sal_Int32 > lcl_tRoleIndexMap;
+
+lcl_tRoleIndexMap lcl_createRoleIndexMap()
+{
+ lcl_tRoleIndexMap aMap;
+ sal_Int32 nIndex = 0;
+
+ aMap[ "label" ] = ++nIndex;
+ aMap[ "categories" ] = ++nIndex;
+ aMap[ "values-x" ] = ++nIndex;
+ aMap[ "values-y" ] = ++nIndex;
+ aMap[ "error-bars-x" ] = ++nIndex;
+ aMap[ "error-bars-x-positive" ] = ++nIndex;
+ aMap[ "error-bars-x-negative" ] = ++nIndex;
+ aMap[ "error-bars-y" ] = ++nIndex;
+ aMap[ "error-bars-y-positive" ] = ++nIndex;
+ aMap[ "error-bars-y-negative" ] = ++nIndex;
+ aMap[ "values-first" ] = ++nIndex;
+ aMap[ "values-min" ] = ++nIndex;
+ aMap[ "values-max" ] = ++nIndex;
+ aMap[ "values-last" ] = ++nIndex;
+ aMap[ "values-size" ] = ++nIndex;
+
+ return aMap;
+}
+
+
+struct lcl_RolesWithRangeAppend
+{
+ typedef Reference< data::XLabeledDataSequence > value_type;
+ typedef ::chart::DialogModel::tRolesWithRanges tContainerType;
+
+ explicit lcl_RolesWithRangeAppend( tContainerType * rCnt,
+ OUString aLabelRole )
+ : m_rDestCnt( rCnt ),
+ m_aRoleForLabelSeq(std::move( aLabelRole ))
+ {}
+
+ lcl_RolesWithRangeAppend & operator= ( const value_type & xVal )
+ {
+ try
+ {
+ if( xVal.is())
+ {
+ // data sequence
+ Reference< data::XDataSequence > xSeq( xVal->getValues());
+ if( xSeq.is())
+ {
+ OUString aRole;
+ Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
+ if( xProp->getPropertyValue( "Role" ) >>= aRole )
+ {
+ m_rDestCnt->emplace(aRole, xSeq->getSourceRangeRepresentation());
+ // label
+ if( aRole == m_aRoleForLabelSeq )
+ {
+ Reference< data::XDataSequence > xLabelSeq( xVal->getLabel());
+ if( xLabelSeq.is())
+ {
+ m_rDestCnt->emplace(
+ lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation());
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return *this;
+ }
+
+ // Implement output operator requirements as required by std::copy (and
+ // implement prefix increment in terms of postfix increment to avoid unused
+ // member function warnings for the latter in the common case where
+ // std::copy would not actually need it):
+ lcl_RolesWithRangeAppend & operator* () { return *this; }
+ lcl_RolesWithRangeAppend & operator++ () { return operator++(0); }
+ lcl_RolesWithRangeAppend & operator++ (int) { return *this; }
+
+private:
+ tContainerType * m_rDestCnt;
+ OUString m_aRoleForLabelSeq;
+};
+
+}
+
+namespace std
+{
+ template<> struct iterator_traits<lcl_RolesWithRangeAppend>
+ {
+ typedef std::output_iterator_tag iterator_category;
+ typedef Reference< data::XLabeledDataSequence > value_type;
+ typedef value_type& reference;
+ };
+}
+
+namespace {
+
+void lcl_SetSequenceRole(
+ const Reference< data::XDataSequence > & xSeq,
+ const OUString & rRole )
+{
+ Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY );
+ if( xProp.is())
+ xProp->setPropertyValue( "Role" , uno::Any( rRole ));
+}
+
+Sequence< OUString > lcl_CopyExcludingValuesFirst(
+ Sequence< OUString > const & i_aInput )
+{
+ Sequence< OUString > aOutput( i_aInput.getLength());
+ auto pOutput = aOutput.getArray();
+ int nSourceIndex, nDestIndex;
+ for( nSourceIndex = nDestIndex = 0; nSourceIndex < i_aInput.getLength(); nSourceIndex++ )
+ {
+ if( i_aInput[nSourceIndex] == "values-first" )
+ {
+ aOutput.realloc( aOutput.getLength() - 1 );
+ pOutput = aOutput.getArray();
+ }
+ else
+ {
+ pOutput[nDestIndex] = i_aInput[nSourceIndex];
+ nDestIndex++;
+ }
+ }
+ return aOutput;
+}
+
+rtl::Reference< ::chart::DataSeries > lcl_CreateNewSeries(
+ const rtl::Reference< ::chart::ChartType > & xChartType,
+ sal_Int32 nNewSeriesIndex,
+ sal_Int32 nTotalNumberOfSeriesInCTGroup,
+ const rtl::Reference< ::chart::Diagram > & xDiagram,
+ const rtl::Reference< ::chart::ChartTypeTemplate > & xTemplate,
+ bool bCreateDataCachedSequences )
+{
+ // create plain series
+ rtl::Reference< ::chart::DataSeries > xResult = new ::chart::DataSeries();
+ if( xTemplate.is())
+ {
+ // @deprecated: correct default color should be found by view
+ // without setting it as hard attribute
+ Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
+ if( xColorScheme.is())
+ xResult->setPropertyValue( "Color" , uno::Any( xColorScheme->getColorByIndex( nNewSeriesIndex )));
+ std::size_t nGroupIndex=0;
+ if( xChartType.is())
+ {
+ std::vector< rtl::Reference< ::chart::ChartType > > aCTs =
+ xDiagram->getChartTypes();
+ for( ; nGroupIndex < aCTs.size(); ++nGroupIndex)
+ if( aCTs[nGroupIndex] == xChartType )
+ break;
+ if( nGroupIndex == aCTs.size())
+ nGroupIndex = 0;
+ }
+ xTemplate->applyStyle2( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup );
+ }
+
+ if( bCreateDataCachedSequences )
+ {
+ // set chart type specific roles
+ if( xChartType.is() )
+ {
+ std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aNewSequences;
+ const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel();
+ const OUString aLabel(::chart::SchResId(STR_DATA_UNNAMED_SERIES));
+ Sequence< OUString > aPossibleRoles( xChartType->getSupportedMandatoryRoles());
+ Sequence< OUString > aPossibleOptRoles( xChartType->getSupportedOptionalRoles());
+
+ //special handling for candlestick type
+ if( xTemplate.is())
+ {
+ rtl::Reference< ::chart::DataInterpreter > xInterpreter( xTemplate->getDataInterpreter2());
+ if( xInterpreter.is())
+ {
+ sal_Int32 nStockVariant;
+ if( xInterpreter->getChartTypeSpecificData("stock variant") >>= nStockVariant )
+ {
+ if( nStockVariant == 0 || nStockVariant == 2) {
+ //delete "values-first" role
+ aPossibleRoles = lcl_CopyExcludingValuesFirst(aPossibleRoles);
+ aPossibleOptRoles = lcl_CopyExcludingValuesFirst(aPossibleOptRoles);
+ }
+ }
+ }
+ }
+
+ const Sequence< OUString > aRoles( aPossibleRoles );
+ const Sequence< OUString > aOptRoles( aPossibleOptRoles );
+
+ for(OUString const & role : aRoles)
+ {
+ if( role == lcl_aLabelRole )
+ continue;
+ Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() );
+ lcl_SetSequenceRole( xSeq, role );
+ // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles
+ if( role == aRoleOfSeqForSeriesLabel )
+ {
+ Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel ));
+ lcl_SetSequenceRole( xLabel, lcl_aLabelRole );
+ aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel ));
+ }
+ else
+ aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
+ }
+
+ for(OUString const & role : aOptRoles)
+ {
+ if( role == lcl_aLabelRole )
+ continue;
+ Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence());
+ lcl_SetSequenceRole( xSeq, role );
+ aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq ));
+ }
+
+ xResult->setData( aNewSequences );
+ }
+ }
+
+ return xResult;
+}
+
+struct lcl_addSeriesNumber
+{
+ sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const
+ {
+ if( xCnt.is())
+ return nCurrentNumber + (xCnt->getDataSeries().getLength());
+ return nCurrentNumber;
+ }
+};
+
+} // anonymous namespace
+
+namespace chart
+{
+
+DialogModelTimeBasedInfo::DialogModelTimeBasedInfo():
+ bTimeBased(false),
+ nStart(0),
+ nEnd(0)
+{
+}
+
+DialogModel::DialogModel(
+ rtl::Reference<::chart::ChartModel> xChartDocument ) :
+ m_xChartDocument(std::move( xChartDocument )),
+ m_aTimerTriggeredControllerLock( m_xChartDocument )
+{
+}
+
+DialogModel::~DialogModel()
+{
+ if(maTimeBasedInfo.bTimeBased)
+ {
+ getModel().setTimeBasedRange(maTimeBasedInfo.nStart, maTimeBasedInfo.nEnd);
+ }
+}
+
+void DialogModel::setTemplate(
+ const rtl::Reference< ChartTypeTemplate > & xTemplate )
+{
+ m_xTemplate = xTemplate;
+}
+
+std::shared_ptr< RangeSelectionHelper > const &
+ DialogModel::getRangeSelectionHelper() const
+{
+ if( ! m_spRangeSelectionHelper)
+ m_spRangeSelectionHelper =
+ std::make_shared<RangeSelectionHelper>( m_xChartDocument );
+
+ return m_spRangeSelectionHelper;
+}
+
+const rtl::Reference<::chart::ChartModel> & DialogModel::getChartModel() const
+{
+ return m_xChartDocument;
+}
+
+Reference< data::XDataProvider > DialogModel::getDataProvider() const
+{
+ Reference< data::XDataProvider > xResult;
+ if( m_xChartDocument.is())
+ xResult.set( m_xChartDocument->getDataProvider());
+ return xResult;
+}
+
+std::vector< rtl::Reference< ChartType > >
+ DialogModel::getAllDataSeriesContainers() const
+{
+ std::vector< rtl::Reference< ChartType > > aResult;
+
+ try
+ {
+ if( !m_xChartDocument )
+ return {};
+ rtl::Reference< Diagram > xDiagram = m_xChartDocument->getFirstChartDiagram();
+ if( xDiagram.is())
+ {
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > & aCooSysSeq(
+ xDiagram->getBaseCoordinateSystems());
+ for( rtl::Reference< BaseCoordinateSystem > const & coords : aCooSysSeq )
+ {
+
+ for (const auto & rxChartType : coords->getChartTypes2())
+ aResult.push_back(rxChartType);
+ }
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ return aResult;
+}
+
+std::vector< DialogModel::tSeriesWithChartTypeByName >
+ DialogModel::getAllDataSeriesWithLabel() const
+{
+ std::vector< tSeriesWithChartTypeByName > aResult;
+ std::vector< rtl::Reference< ChartType > > aContainers(
+ getAllDataSeriesContainers());
+
+ for (const auto & rxChartType : aContainers )
+ {
+ try
+ {
+ const std::vector< rtl::Reference< DataSeries > > & aSeq = rxChartType->getDataSeries2();
+ OUString aRole = rxChartType->getRoleOfSequenceForSeriesLabel();
+ for( rtl::Reference< DataSeries > const & dataSeries : aSeq )
+ {
+ aResult.push_back(
+ ::chart::DialogModel::tSeriesWithChartTypeByName(
+ dataSeries->getLabelForRole( aRole ),
+ std::make_pair( dataSeries, rxChartType )));
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+
+ return aResult;
+}
+
+namespace {
+
+void addMissingRoles(DialogModel::tRolesWithRanges& rResult, const uno::Sequence<OUString>& rRoles)
+{
+ for(OUString const & role : rRoles)
+ {
+ if(rResult.find(role) == rResult.end())
+ rResult.emplace(role, OUString());
+ }
+}
+
+/**
+ * Insert a new data series to chart type at position after specified series
+ * position.
+ *
+ * @param xChartType chart type that contains data series.
+ * @param xSeries insertion position. The new series will be inserted after
+ * this one.
+ * @param xNewSeries new data series to insert.
+ */
+void addNewSeriesToContainer(
+ const rtl::Reference<ChartType>& xChartType,
+ const rtl::Reference<DataSeries>& xSeries,
+ const rtl::Reference<DataSeries>& xNewSeries )
+{
+ auto aSeries = xChartType->getDataSeries2();
+
+ auto aIt = std::find( aSeries.begin(), aSeries.end(), xSeries);
+
+ if( aIt == aSeries.end())
+ // if we have no series we insert at the first position.
+ aIt = aSeries.begin();
+ else
+ // vector::insert inserts before, so we have to advance
+ ++aIt;
+
+ aSeries.insert(aIt, xNewSeries);
+ xChartType->setDataSeries(aSeries);
+}
+
+}
+
+DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges(
+ const Reference< XDataSeries > & xSeries,
+ const OUString & aRoleOfSequenceForLabel,
+ const rtl::Reference< ::chart::ChartType > & xChartType )
+{
+ DialogModel::tRolesWithRanges aResult;
+ try
+ {
+ Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW );
+ const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences());
+ std::copy( aSeq.begin(), aSeq.end(),
+ lcl_RolesWithRangeAppend( &aResult, aRoleOfSequenceForLabel ));
+ if( xChartType.is())
+ {
+ // add missing mandatory roles
+ Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles());
+ addMissingRoles(aResult, aRoles);
+
+ // add missing optional roles
+ aRoles = xChartType->getSupportedOptionalRoles();
+ addMissingRoles(aResult, aRoles);
+
+ // add missing property roles
+ aRoles = xChartType->getSupportedPropertyRoles();
+ addMissingRoles(aResult, aRoles);
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return aResult;
+}
+
+void DialogModel::moveSeries(
+ const rtl::Reference< DataSeries > & xSeries,
+ MoveDirection eDirection )
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
+ xDiagram->moveSeries( xSeries, eDirection==MoveDirection::Down );
+}
+
+rtl::Reference< ::chart::DataSeries > DialogModel::insertSeriesAfter(
+ const Reference< XDataSeries > & xUnoSeries,
+ const rtl::Reference< ::chart::ChartType > & xChartType,
+ bool bCreateDataCachedSequences /* = false */ )
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+ rtl::Reference< ::chart::DataSeries > xNewSeries;
+ rtl::Reference<DataSeries> xSeries = dynamic_cast<DataSeries*>(xUnoSeries.get());
+ assert(xSeries || !xUnoSeries);
+
+ try
+ {
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram() );
+ ThreeDLookScheme e3DScheme = xDiagram->detectScheme();
+
+ sal_Int32 nSeriesInChartType = 0;
+ const sal_Int32 nTotalSeries = countSeries();
+ if( xChartType.is())
+ {
+ nSeriesInChartType = xChartType->getDataSeries().getLength();
+ }
+
+ // create new series
+ xNewSeries =
+ lcl_CreateNewSeries(
+ xChartType,
+ nTotalSeries, // new series' index
+ nSeriesInChartType,
+ xDiagram,
+ m_xTemplate,
+ bCreateDataCachedSequences );
+
+ // add new series to container
+ if( xNewSeries.is())
+ addNewSeriesToContainer(xChartType, xSeries, xNewSeries);
+
+ xDiagram->setScheme( e3DScheme );
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return xNewSeries;
+}
+
+void DialogModel::deleteSeries(
+ const rtl::Reference< DataSeries > & xSeries,
+ const rtl::Reference< ChartType > & xChartType )
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+
+ DataSeriesHelper::deleteSeries( xSeries, xChartType );
+}
+
+uno::Reference< chart2::data::XLabeledDataSequence > DialogModel::getCategories() const
+{
+ uno::Reference< chart2::data::XLabeledDataSequence > xResult;
+ try
+ {
+ if( m_xChartDocument.is())
+ {
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
+ if (xDiagram.is())
+ xResult = xDiagram->getCategories();
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return xResult;
+}
+
+void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories )
+{
+ if( !m_xChartDocument.is())
+ return;
+
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
+ if( !xDiagram.is())
+ return;
+
+ // categories
+ bool bSupportsCategories = true;
+
+ rtl::Reference< ChartType > xFirstChartType( xDiagram->getChartTypeByIndex( 0 ) );
+ if( xFirstChartType.is() )
+ {
+ sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis
+ bSupportsCategories = (nAxisType == AxisType::CATEGORY);
+ }
+ xDiagram->setCategories( xCategories, true, bSupportsCategories );
+}
+
+OUString DialogModel::getCategoriesRange() const
+{
+ OUString aRange;
+ try
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLSeq( getCategories());
+ if( xLSeq.is())
+ {
+ Reference< data::XDataSequence > xSeq( xLSeq->getValues());
+ if( xSeq.is())
+ aRange = xSeq->getSourceRangeRepresentation();
+ }
+ }
+ catch (const lang::DisposedException&)
+ {
+ TOOLS_WARN_EXCEPTION( "chart2", "unexpected exception caught" );
+ }
+ return aRange;
+}
+
+bool DialogModel::isCategoryDiagram() const
+{
+ bool bRet = false;
+ if( m_xChartDocument.is() && m_xChartDocument->getFirstChartDiagram())
+ bRet = m_xChartDocument->getFirstChartDiagram()->isCategory();
+ return bRet;
+}
+
+void DialogModel::detectArguments(
+ OUString & rOutRangeString,
+ bool & rOutUseColumns,
+ bool & rOutFirstCellAsLabel,
+ bool & rOutHasCategories ) const
+{
+ try
+ {
+ uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX
+
+ // Note: unused data is currently not supported in being passed to detectRangeSegmentation
+ if( m_xChartDocument.is())
+ {
+ (void)DataSourceHelper::detectRangeSegmentation(
+ m_xChartDocument,
+ rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories );
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+bool DialogModel::allArgumentsForRectRangeDetected() const
+{
+ return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument );
+}
+
+void DialogModel::startControllerLockTimer()
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+}
+
+void DialogModel::setData(
+ const Sequence< beans::PropertyValue > & rArguments )
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ ControllerLockGuardUNO aLockedControllers( m_xChartDocument );
+
+ Reference< data::XDataProvider > xDataProvider( getDataProvider());
+ if( ! xDataProvider.is() ||
+ ! m_xTemplate.is() )
+ {
+ OSL_FAIL( "Model objects missing" );
+ return;
+ }
+
+ try
+ {
+ Reference< chart2::data::XDataSource > xDataSource(
+ xDataProvider->createDataSource( rArguments ) );
+
+ rtl::Reference< ::chart::DataInterpreter > xInterpreter(
+ m_xTemplate->getDataInterpreter2());
+ if( xInterpreter.is())
+ {
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram() );
+ ThreeDLookScheme e3DScheme = xDiagram->detectScheme();
+
+ std::vector< rtl::Reference< DataSeries > > aSeriesToReUse =
+ xDiagram->getDataSeries();
+ applyInterpretedData(
+ xInterpreter->interpretDataSource(
+ xDataSource, rArguments,
+ aSeriesToReUse ),
+ aSeriesToReUse);
+
+ xDiagram->setScheme( e3DScheme );
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+void DialogModel::setTimeBasedRange( bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const
+{
+ maTimeBasedInfo.nStart = nStart;
+ maTimeBasedInfo.nEnd = nEnd;
+ maTimeBasedInfo.bTimeBased = bTimeBased;
+}
+
+OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
+{
+ return lcl_ConvertRole( rRoleString );
+}
+
+OUString DialogModel::GetRoleDataLabel()
+{
+ return ::chart::SchResId(STR_OBJECT_DATALABELS);
+}
+
+sal_Int32 DialogModel::GetRoleIndexForSorting( const OUString & rInternalRoleString )
+{
+ static lcl_tRoleIndexMap aRoleIndexMap = lcl_createRoleIndexMap();
+
+ lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString ));
+ if( aIt != aRoleIndexMap.end())
+ return aIt->second;
+
+ return 0;
+}
+
+// private methods
+
+void DialogModel::applyInterpretedData(
+ const InterpretedData & rNewData,
+ const std::vector< rtl::Reference< DataSeries > > & rSeriesToReUse )
+{
+ if( ! m_xChartDocument.is())
+ return;
+
+ m_aTimerTriggeredControllerLock.startTimer();
+ rtl::Reference< Diagram > xDiagram( m_xChartDocument->getFirstChartDiagram());
+ if( !xDiagram.is())
+ return;
+
+ // styles
+ if( m_xTemplate.is() )
+ {
+ sal_Int32 nGroup = 0;
+ sal_Int32 nSeriesCounter = 0;
+ sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size());
+ const sal_Int32 nOuterSize=rNewData.Series.size();
+
+ for(; nGroup < nOuterSize; ++nGroup)
+ {
+ const std::vector< rtl::Reference< DataSeries > > & aSeries( rNewData.Series[ nGroup ] );
+ const sal_Int32 nSeriesInGroup = aSeries.size();
+ for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter )
+ {
+ if( std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] )
+ == rSeriesToReUse.end())
+ {
+ if( aSeries[nSeries].is())
+ {
+ // @deprecated: correct default color should be found by view
+ // without setting it as hard attribute
+ Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
+ if( xColorScheme.is())
+ aSeries[nSeries]->setPropertyValue( "Color" ,
+ uno::Any( xColorScheme->getColorByIndex( nSeriesCounter )));
+ }
+ m_xTemplate->applyStyle2( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup );
+ }
+ }
+ }
+ }
+
+ // data series
+ std::vector< rtl::Reference< ChartType > > aSeriesCnt = getAllDataSeriesContainers();
+
+ OSL_ASSERT( aSeriesCnt.size() == rNewData.Series.size());
+
+ auto aSrcIt = rNewData.Series.begin();
+ auto aDestIt = aSeriesCnt.begin();
+ for(; aSrcIt != rNewData.Series.end() && aDestIt != aSeriesCnt.end();
+ ++aSrcIt, ++aDestIt )
+ {
+ try
+ {
+ OSL_ASSERT( (*aDestIt).is());
+ (*aDestIt)->setDataSeries( *aSrcIt );
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+
+ DialogModel::setCategories(rNewData.Categories);
+}
+
+sal_Int32 DialogModel::countSeries() const
+{
+ std::vector< rtl::Reference< ChartType > > aCnt( getAllDataSeriesContainers());
+ return std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber());
+}
+
+ChartModel& DialogModel::getModel() const
+{
+ return *m_xChartDocument;
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/DialogModel.hxx b/chart2/source/controller/dialogs/DialogModel.hxx
new file mode 100644
index 0000000000..325cffe067
--- /dev/null
+++ b/chart2/source/controller/dialogs/DialogModel.hxx
@@ -0,0 +1,176 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <TimerTriggeredControllerLock.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ref.hxx>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace chart { class ChartModel; }
+namespace com::sun::star::beans { struct PropertyValue; }
+namespace com::sun::star::chart2 { class XChartDocument; }
+namespace com::sun::star::frame { class XModel; }
+namespace com::sun::star::uno { class XComponentContext; }
+namespace com::sun::star::uno { template <class E> class Sequence; }
+
+namespace com::sun::star::chart2 {
+ class XDataSeriesContainer;
+ class XDataSeries;
+ class XChartType;
+ namespace data {
+ class XDataProvider;
+ class XLabeledDataSequence;
+ }
+}
+
+namespace chart
+{
+class ChartType;
+class ChartTypeTemplate;
+class DataSeries;
+struct InterpretedData;
+class LabeledDataSequence;
+class RangeSelectionHelper;
+
+struct DialogModelTimeBasedInfo
+{
+ DialogModelTimeBasedInfo();
+
+ bool bTimeBased;
+ sal_Int32 nStart;
+ sal_Int32 nEnd;
+};
+
+class DialogModel
+{
+public:
+ explicit DialogModel( rtl::Reference<::chart::ChartModel> xChartDocument );
+ ~DialogModel();
+
+ typedef std::pair<
+ OUString,
+ std::pair< rtl::Reference< ::chart::DataSeries >,
+ rtl::Reference< ::chart::ChartType > > >
+ tSeriesWithChartTypeByName;
+
+ typedef std::map< OUString, OUString >
+ tRolesWithRanges;
+
+ void setTemplate(
+ const rtl::Reference< ::chart::ChartTypeTemplate > & xTemplate );
+
+ std::shared_ptr< RangeSelectionHelper > const &
+ getRangeSelectionHelper() const;
+
+ const rtl::Reference<::chart::ChartModel> &
+ getChartModel() const;
+
+ css::uno::Reference< css::chart2::data::XDataProvider >
+ getDataProvider() const;
+
+ std::vector< rtl::Reference< ::chart::ChartType > >
+ getAllDataSeriesContainers() const;
+
+ std::vector< tSeriesWithChartTypeByName >
+ getAllDataSeriesWithLabel() const;
+
+ static tRolesWithRanges getRolesWithRanges(
+ const css::uno::Reference< css::chart2::XDataSeries > & xSeries,
+ const OUString & aRoleOfSequenceForLabel,
+ const rtl::Reference< ::chart::ChartType > & xChartType );
+
+ enum class MoveDirection
+ {
+ Down, Up
+ };
+
+ void moveSeries( const rtl::Reference< DataSeries > & xSeries,
+ MoveDirection eDirection );
+
+ /// @return the newly inserted series
+ rtl::Reference<
+ ::chart::DataSeries > insertSeriesAfter(
+ const css::uno::Reference< css::chart2::XDataSeries > & xSeries,
+ const rtl::Reference< ::chart::ChartType > & xChartType,
+ bool bCreateDataCachedSequences = false );
+
+ void deleteSeries(
+ const rtl::Reference< ::chart::DataSeries > & xSeries,
+ const rtl::Reference< ::chart::ChartType > & xChartType );
+
+ css::uno::Reference< css::chart2::data::XLabeledDataSequence >
+ getCategories() const;
+
+ void setCategories( const css::uno::Reference< css::chart2::data::XLabeledDataSequence > & xCategories );
+
+ OUString getCategoriesRange() const;
+
+ bool isCategoryDiagram() const;
+
+ void detectArguments(
+ OUString & rOutRangeString,
+ bool & rOutUseColumns, bool & rOutFirstCellAsLabel, bool & rOutHasCategories ) const;
+
+ bool allArgumentsForRectRangeDetected() const;
+
+ void setData( const css::uno::Sequence< css::beans::PropertyValue > & rArguments );
+
+ void setTimeBasedRange( bool bTimeBased, sal_Int32 nStart, sal_Int32 nEnd) const;
+
+ const DialogModelTimeBasedInfo& getTimeBasedInfo() const { return maTimeBasedInfo; }
+
+ void startControllerLockTimer();
+
+ static OUString ConvertRoleFromInternalToUI( const OUString & rRoleString );
+ static OUString GetRoleDataLabel();
+
+ // pass a role string (not translated) and get an index that serves for
+ // relative ordering, to get e.g. x-values and y-values in the right order
+ static sal_Int32 GetRoleIndexForSorting( const OUString & rInternalRoleString );
+
+ ChartModel& getModel() const;
+
+private:
+ rtl::Reference<::chart::ChartModel>
+ m_xChartDocument;
+
+ rtl::Reference< ::chart::ChartTypeTemplate > m_xTemplate;
+
+ mutable std::shared_ptr< RangeSelectionHelper >
+ m_spRangeSelectionHelper;
+
+ TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
+
+private:
+ void applyInterpretedData(
+ const InterpretedData & rNewData,
+ const std::vector< rtl::Reference< ::chart::DataSeries > > & rSeriesToReUse );
+
+ sal_Int32 countSeries() const;
+
+ mutable DialogModelTimeBasedInfo maTimeBasedInfo;
+};
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/ObjectNameProvider.cxx b/chart2/source/controller/dialogs/ObjectNameProvider.cxx
new file mode 100644
index 0000000000..2097e43c21
--- /dev/null
+++ b/chart2/source/controller/dialogs/ObjectNameProvider.cxx
@@ -0,0 +1,868 @@
+/* -*- 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 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <ObjectNameProvider.hxx>
+#include <ResId.hxx>
+#include <strings.hrc>
+#include <Axis.hxx>
+#include <AxisHelper.hxx>
+#include <ChartModel.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartType.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <TitleHelper.hxx>
+#include <ExplicitCategoriesProvider.hxx>
+#include <CommonConverters.hxx>
+#include <NumberFormatterWrapper.hxx>
+#include <RegressionCurveHelper.hxx>
+#include <BaseCoordinateSystem.hxx>
+#include <RegressionCurveModel.hxx>
+#include <rtl/math.hxx>
+#include <rtl/ustring.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <com/sun/star/chart2/XTitle.hpp>
+#include <com/sun/star/chart2/MovingAverageType.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+
+namespace
+{
+
+OUString lcl_getDataSeriesName( std::u16string_view rObjectCID, const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel );
+ if( xDiagram.is() && xSeries.is() )
+ {
+ rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xSeries ) );
+ if( xChartType.is() )
+ {
+ aRet = xSeries->getLabelForRole(
+ xChartType->getRoleOfSequenceForSeriesLabel() ) ;
+ }
+ }
+
+ return aRet;
+}
+
+OUString lcl_getFullSeriesName( std::u16string_view rObjectCID, const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet(SchResId(STR_TIP_DATASERIES));
+ OUString aWildcard( "%SERIESNAME" );
+ sal_Int32 nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
+ return aRet;
+}
+
+void lcl_addText( OUString& rOut, std::u16string_view rSeparator, std::u16string_view rNext )
+{
+ if( !(rOut.isEmpty() || rNext.empty()) )
+ rOut+=rSeparator;
+ if( !rNext.empty() )
+ rOut+=rNext;
+}
+
+OUString lcl_getDataPointValueText( const rtl::Reference< DataSeries >& xSeries, sal_Int32 nPointIndex,
+ const rtl::Reference< BaseCoordinateSystem >& xCooSys,
+ const Reference< frame::XModel >& xChartModel )
+{
+
+ OUString aRet;
+
+ if(!xSeries.is())
+ return aRet;
+
+ const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aDataSequences = xSeries->getDataSequences2();
+
+ OUString aX, aY, aY_Min, aY_Max, aY_First, aY_Last, a_Size;
+ double fValue = 0;
+
+ uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY );
+ NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
+ Color nLabelColor;//dummy
+ bool bColorChanged;//dummy
+
+ for(sal_Int32 nN = aDataSequences.size();nN--;)
+ {
+ uno::Reference<data::XDataSequence> xDataSequence( aDataSequences[nN]->getValues());
+ if( !xDataSequence.is() )
+ continue;
+
+ try
+ {
+ Sequence< Any > aData( xDataSequence->getData() );
+
+ if( nPointIndex >= aData.getLength() )
+ continue;
+ uno::Reference<beans::XPropertySet> xProp(xDataSequence, uno::UNO_QUERY );
+ if( xProp.is())
+ {
+ uno::Any aARole = xProp->getPropertyValue( "Role" );
+ OUString aRole;
+ aARole >>= aRole;
+
+ if( aRole == "values-x" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aX = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-y")
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aY = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-first" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aY_First = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-min" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aY_Min = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-max" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aY_Max = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-last" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ aY_Last = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ else if( aRole == "values-size" )
+ {
+ aData[nPointIndex]>>= fValue;
+ sal_Int32 nNumberFormatKey = xDataSequence->getNumberFormatKeyByIndex( nPointIndex );
+ a_Size = aNumberFormatterWrapper.getFormattedString( nNumberFormatKey, fValue, nLabelColor, bColorChanged );
+ }
+ }
+ }
+ catch (const lang::DisposedException&)
+ {
+ TOOLS_WARN_EXCEPTION( "chart2", "unexpected exception caught" );
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("chart2", "" );
+ }
+ }
+
+ if( aX.isEmpty() )
+ {
+ ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartModel);
+ aRet = ExplicitCategoriesProvider::getCategoryByIndex( xCooSys, rModel, nPointIndex );
+ }
+ else
+ {
+ aRet = aX;
+ }
+
+ OUString aSeparator( " " );
+
+ lcl_addText( aRet, aSeparator, aY );
+ lcl_addText( aRet, aSeparator, aY_First );
+ lcl_addText( aRet, aSeparator, aY_Min );
+ lcl_addText( aRet, aSeparator, aY_Max );
+ lcl_addText( aRet, aSeparator, aY_Last );
+ lcl_addText( aRet, aSeparator, a_Size );
+
+ return aRet;
+}
+
+} //end anonymous namespace
+
+OUString ObjectNameProvider::getName( ObjectType eObjectType, bool bPlural )
+{
+ OUString aRet;
+ switch( eObjectType )
+ {
+ case OBJECTTYPE_PAGE:
+ aRet=SchResId(STR_OBJECT_PAGE);
+ break;
+ case OBJECTTYPE_TITLE:
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_TITLES);
+ else
+ aRet=SchResId(STR_OBJECT_TITLE);
+ }
+ break;
+ case OBJECTTYPE_LEGEND:
+ aRet=SchResId(STR_OBJECT_LEGEND);
+ break;
+ case OBJECTTYPE_LEGEND_ENTRY:
+ aRet=SchResId(STR_OBJECT_LEGEND_SYMBOL);//@todo change string if we do differentiate symbol and legend entry in future
+ break;
+ case OBJECTTYPE_DIAGRAM:
+ aRet=SchResId(STR_OBJECT_DIAGRAM);
+ break;
+ case OBJECTTYPE_DIAGRAM_WALL:
+ aRet=SchResId(STR_OBJECT_DIAGRAM_WALL);
+ break;
+ case OBJECTTYPE_DIAGRAM_FLOOR:
+ aRet=SchResId(STR_OBJECT_DIAGRAM_FLOOR);
+ break;
+ case OBJECTTYPE_AXIS:
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_AXES);
+ else
+ aRet=SchResId(STR_OBJECT_AXIS);
+ }
+ break;
+ case OBJECTTYPE_AXIS_UNITLABEL:
+ aRet=SchResId(STR_OBJECT_LABEL);//@todo maybe a more concrete name
+ break;
+ case OBJECTTYPE_GRID:
+ case OBJECTTYPE_SUBGRID: //maybe todo: different names for subgrids
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_GRIDS);
+ else
+ aRet=SchResId(STR_OBJECT_GRID);
+ }
+ break;
+ case OBJECTTYPE_DATA_SERIES:
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_DATASERIES_PLURAL);
+ else
+ aRet=SchResId(STR_OBJECT_DATASERIES);
+ }
+ break;
+ case OBJECTTYPE_DATA_POINT:
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_DATAPOINTS);
+ else
+ aRet=SchResId(STR_OBJECT_DATAPOINT);
+ }
+ break;
+ case OBJECTTYPE_DATA_LABELS:
+ aRet=SchResId(STR_OBJECT_DATALABELS);
+ break;
+ case OBJECTTYPE_DATA_LABEL:
+ aRet=SchResId(STR_OBJECT_LABEL);
+ break;
+ case OBJECTTYPE_DATA_ERRORS_X:
+ aRet=SchResId(STR_OBJECT_ERROR_BARS_X);
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ aRet=SchResId(STR_OBJECT_ERROR_BARS_Y);
+ break;
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ aRet=SchResId(STR_OBJECT_ERROR_BARS_Z);
+ break;
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ aRet=SchResId(STR_OBJECT_AVERAGE_LINE);
+ break;
+ case OBJECTTYPE_DATA_CURVE:
+ {
+ if(bPlural)
+ aRet=SchResId(STR_OBJECT_CURVES);
+ else
+ aRet=SchResId(STR_OBJECT_CURVE);
+ }
+ break;
+ case OBJECTTYPE_DATA_STOCK_RANGE:
+ break;
+ case OBJECTTYPE_DATA_STOCK_LOSS:
+ aRet=SchResId(STR_OBJECT_STOCK_LOSS);
+ break;
+ case OBJECTTYPE_DATA_STOCK_GAIN:
+ aRet=SchResId(STR_OBJECT_STOCK_GAIN);
+ break;
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ aRet=SchResId(STR_OBJECT_CURVE_EQUATION);
+ break;
+ case OBJECTTYPE_DATA_TABLE:
+ aRet=SchResId(STR_DATA_TABLE);
+ break;
+ default: //OBJECTTYPE_UNKNOWN
+ ;
+ }
+ return aRet;
+}
+
+OUString ObjectNameProvider::getAxisName( std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ rtl::Reference< ::chart::Axis > xAxis =
+ dynamic_cast<::chart::Axis*>(ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ).get());
+
+ sal_Int32 nCooSysIndex = 0;
+ sal_Int32 nDimensionIndex = 0;
+ sal_Int32 nAxisIndex = 0;
+ AxisHelper::getIndicesForAxis( xAxis, xChartModel->getFirstChartDiagram(), nCooSysIndex, nDimensionIndex, nAxisIndex );
+
+ switch(nDimensionIndex)
+ {
+ case 0://x-axis
+ if( nAxisIndex == 0 )
+ aRet=SchResId(STR_OBJECT_AXIS_X);
+ else
+ aRet=SchResId(STR_OBJECT_SECONDARY_X_AXIS);
+ break;
+ case 1://y-axis
+ if( nAxisIndex == 0 )
+ aRet=SchResId(STR_OBJECT_AXIS_Y);
+ else
+ aRet=SchResId(STR_OBJECT_SECONDARY_Y_AXIS);
+ break;
+ case 2://z-axis
+ aRet=SchResId(STR_OBJECT_AXIS_Z);
+ break;
+ default://axis
+ aRet=SchResId(STR_OBJECT_AXIS);
+ break;
+ }
+
+ return aRet;
+}
+
+OUString ObjectNameProvider::getTitleNameByType( TitleHelper::eTitleType eType )
+{
+ OUString aRet;
+
+ switch(eType)
+ {
+ case TitleHelper::MAIN_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_MAIN);
+ break;
+ case TitleHelper::SUB_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_SUB);
+ break;
+ case TitleHelper::X_AXIS_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_X_AXIS);
+ break;
+ case TitleHelper::Y_AXIS_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_Y_AXIS);
+ break;
+ case TitleHelper::Z_AXIS_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_Z_AXIS);
+ break;
+ case TitleHelper::SECONDARY_X_AXIS_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_SECONDARY_X_AXIS);
+ break;
+ case TitleHelper::SECONDARY_Y_AXIS_TITLE:
+ aRet=SchResId(STR_OBJECT_TITLE_SECONDARY_Y_AXIS);
+ break;
+ default:
+ OSL_FAIL("unknown title type");
+ break;
+ }
+
+ if( aRet.isEmpty() )
+ aRet=SchResId(STR_OBJECT_TITLE);
+
+ return aRet;
+}
+
+OUString ObjectNameProvider::getTitleName( std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ rtl::Reference<Title> xTitle =
+ dynamic_cast<Title*>(ObjectIdentifier::getObjectPropertySet( rObjectCID , xChartModel ).get());
+ if( xTitle )
+ {
+ TitleHelper::eTitleType eType;
+ if( TitleHelper::getTitleType( eType, xTitle, xChartModel ) )
+ aRet = ObjectNameProvider::getTitleNameByType( eType );
+ }
+ if( aRet.isEmpty() )
+ aRet=SchResId(STR_OBJECT_TITLE);
+
+ return aRet;
+}
+
+OUString ObjectNameProvider::getGridName( std::u16string_view rObjectCID
+ , const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ OUString aRet;
+
+ sal_Int32 nCooSysIndex = -1;
+ sal_Int32 nDimensionIndex = -1;
+ sal_Int32 nAxisIndex = -1;
+ rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( rObjectCID , xChartModel );
+ AxisHelper::getIndicesForAxis( xAxis, xChartModel->getFirstChartDiagram()
+ , nCooSysIndex , nDimensionIndex, nAxisIndex );
+
+ bool bMainGrid = (ObjectIdentifier::getObjectType( rObjectCID ) == OBJECTTYPE_GRID);
+
+ if( bMainGrid )
+ {
+ switch(nDimensionIndex)
+ {
+ case 0://x-axis
+ aRet=SchResId(STR_OBJECT_GRID_MAJOR_X);
+ break;
+ case 1://y-axis
+ aRet=SchResId(STR_OBJECT_GRID_MAJOR_Y);
+ break;
+ case 2://z-axis
+ aRet=SchResId(STR_OBJECT_GRID_MAJOR_Z);
+ break;
+ default://axis
+ aRet=SchResId(STR_OBJECT_GRID);
+ break;
+ }
+ }
+ else
+ {
+ switch(nDimensionIndex)
+ {
+ case 0://x-axis
+ aRet=SchResId(STR_OBJECT_GRID_MINOR_X);
+ break;
+ case 1://y-axis
+ aRet=SchResId(STR_OBJECT_GRID_MINOR_Y);
+ break;
+ case 2://z-axis
+ aRet=SchResId(STR_OBJECT_GRID_MINOR_Z);
+ break;
+ default://axis
+ aRet=SchResId(STR_OBJECT_GRID);
+ break;
+ }
+ }
+ return aRet;
+}
+
+OUString ObjectNameProvider::getHelpText( std::u16string_view rObjectCID, const rtl::Reference<::chart::ChartModel>& xChartModel, bool bVerbose )
+{
+ OUString aRet;
+ ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
+ if( eObjectType == OBJECTTYPE_AXIS )
+ {
+ aRet=ObjectNameProvider::getAxisName( rObjectCID, xChartModel );
+ }
+ else if( eObjectType == OBJECTTYPE_GRID
+ || eObjectType == OBJECTTYPE_SUBGRID )
+ {
+ aRet=ObjectNameProvider::getGridName( rObjectCID, xChartModel );
+ }
+ else if( eObjectType == OBJECTTYPE_TITLE )
+ {
+ aRet=ObjectNameProvider::getTitleName( rObjectCID, xChartModel );
+ }
+ else if( eObjectType == OBJECTTYPE_DATA_SERIES )
+ {
+ aRet = lcl_getFullSeriesName( rObjectCID, xChartModel );
+ }
+ else if( eObjectType == OBJECTTYPE_DATA_POINT )
+ {
+ if( bVerbose )
+ {
+ aRet= SchResId(STR_TIP_DATAPOINT_INDEX) + "\n"
+ + SchResId(STR_TIP_DATASERIES) + "\n"
+ + SchResId(STR_TIP_DATAPOINT_VALUES);
+ }
+ else
+ aRet=SchResId(STR_TIP_DATAPOINT);
+
+ rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel );
+ if( xDiagram.is() && xSeries.is() )
+ {
+ sal_Int32 nPointIndex = o3tl::toInt32(ObjectIdentifier::getParticleID(rObjectCID));
+
+ //replace data point index
+ OUString aWildcard( "%POINTNUMBER" );
+ sal_Int32 nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ {
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), OUString::number(nPointIndex+1) );
+ }
+
+ //replace data series index
+ aWildcard = "%SERIESNUMBER";
+ nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ {
+ std::vector< rtl::Reference< DataSeries > > aSeriesVector =
+ xDiagram->getDataSeries();
+ sal_Int32 nSeriesIndex = -1;
+ for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
+ {
+ if( aSeriesVector[nSeriesIndex] == xSeries )
+ {
+ break;
+ }
+ }
+
+ OUString aReplacement( OUString::number(nSeriesIndex+1) );
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), aReplacement );
+ }
+
+ //replace point values
+ aWildcard = "%POINTVALUES";
+ nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataPointValueText(
+ xSeries,nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartModel ) );
+
+ //replace series name
+ aWildcard = "%SERIESNAME";
+ nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), lcl_getDataSeriesName( rObjectCID, xChartModel ) );
+ }
+ }
+ else if( eObjectType == OBJECTTYPE_DATA_CURVE )
+ {
+ if( bVerbose )
+ {
+ aRet = SchResId( STR_OBJECT_CURVE_WITH_PARAMETERS );
+ rtl::Reference< DataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
+
+ if( xSeries.is())
+ {
+ sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
+ rtl::Reference< RegressionCurveModel > xCurve = RegressionCurveHelper::getRegressionCurveAtIndex(xSeries, nCurveIndex);
+ if( xCurve.is())
+ {
+ try
+ {
+ Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_SET_THROW );
+ sal_Int32 aDegree = 2;
+ sal_Int32 aPeriod = 2;
+ sal_Int32 aMovingType = css::chart2::MovingAverageType::Prior;
+ bool bForceIntercept = false;
+ double aInterceptValue = 0.0;
+ OUString aXName ("x"), aYName ("f(x)");
+ const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
+ const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep();
+ sal_Unicode cDecSeparator = aNumDecimalSep[0];
+
+ xCurve->getPropertyValue( "PolynomialDegree") >>= aDegree;
+ xCurve->getPropertyValue( "MovingAveragePeriod") >>= aPeriod;
+ xCurve->getPropertyValue( "MovingAverageType") >>= aMovingType;
+ xCurve->getPropertyValue( "ForceIntercept") >>= bForceIntercept;
+ if (bForceIntercept)
+ xCurve->getPropertyValue( "InterceptValue") >>= aInterceptValue;
+ uno::Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties());
+ if( xEqProp.is())
+ {
+ if ( !(xEqProp->getPropertyValue( "XName") >>= aXName) )
+ aXName = "x";
+ if ( !(xEqProp->getPropertyValue( "YName") >>= aYName) )
+ aYName = "f(x)";
+ }
+ xCalculator->setRegressionProperties(aDegree, bForceIntercept, aInterceptValue, aPeriod, aMovingType);
+ xCalculator->setXYNames ( aXName, aYName );
+ RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );
+
+ // change text for Moving Average
+ if ( RegressionCurveHelper::getRegressionType( xCurve ) == SvxChartRegress::MovingAverage )
+ {
+ aRet = xCalculator->getRepresentation();
+ }
+ else
+ {
+ // replace formula
+ OUString aWildcard = "%FORMULA";
+ sal_Int32 nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ {
+ OUString aFormula ( xCalculator->getRepresentation() );
+ if ( cDecSeparator != '.' )
+ {
+ aFormula = aFormula.replace( '.', cDecSeparator );
+ }
+ aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), aFormula );
+ }
+
+ // replace r^2
+ aWildcard = "%RSQUARED";
+ nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ {
+ double fR( xCalculator->getCorrelationCoefficient());
+ aRet = aRet.replaceAt(
+ nIndex, aWildcard.getLength(),
+ ::rtl::math::doubleToUString(
+ fR*fR, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
+ }
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ }
+ }
+ else
+ {
+ rtl::Reference< DataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(rObjectCID , xChartModel));
+ aRet += getName(eObjectType);
+
+ if( xSeries.is())
+ {
+ sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
+ rtl::Reference< RegressionCurveModel > xCurve( RegressionCurveHelper::getRegressionCurveAtIndex(xSeries, nCurveIndex) );
+ if( xCurve.is())
+ {
+ aRet += " (" + RegressionCurveHelper::getRegressionCurveName(xCurve) + " )";
+ }
+ }
+ }
+ }
+ else if( eObjectType == OBJECTTYPE_DATA_AVERAGE_LINE )
+ {
+ if( bVerbose )
+ {
+ aRet = SchResId(STR_OBJECT_AVERAGE_LINE_WITH_PARAMETERS);
+ rtl::Reference< DataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartModel ));
+ if( xSeries.is())
+ {
+ rtl::Reference< RegressionCurveModel > xCurve( RegressionCurveHelper::getMeanValueLine( xSeries ));
+ if( xCurve.is())
+ {
+ try
+ {
+ Reference< chart2::XRegressionCurveCalculator > xCalculator( xCurve->getCalculator(), uno::UNO_SET_THROW );
+ RegressionCurveHelper::initializeCurveCalculator( xCalculator, xSeries, xChartModel );
+
+ const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
+ const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep();
+ sal_Unicode cDecSeparator = aNumDecimalSep[0];
+
+ OUString aWildcard( "%AVERAGE_VALUE" );
+ sal_Int32 nIndex = aRet.indexOf( aWildcard );
+ // as the curve is constant, the value at any x-value is ok
+ if( nIndex != -1 )
+ {
+ const double fMeanValue( xCalculator->getCurveValue( 0.0 ));
+ aRet = aRet.replaceAt(
+ nIndex, aWildcard.getLength(),
+ ::rtl::math::doubleToUString(
+ fMeanValue, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
+ }
+
+ // replace standard deviation
+ aWildcard = "%STD_DEVIATION";
+ nIndex = aRet.indexOf( aWildcard );
+ if( nIndex != -1 )
+ {
+ const double fStdDev( xCalculator->getCorrelationCoefficient());
+ aRet = aRet.replaceAt(
+ nIndex, aWildcard.getLength(),
+ ::rtl::math::doubleToUString(
+ fStdDev, rtl_math_StringFormat_G, 4, cDecSeparator, true ));
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ }
+ }
+ else
+ {
+ // non-verbose
+ aRet = ObjectNameProvider::getName( eObjectType );
+ }
+ }
+ else
+ {
+ aRet = ObjectNameProvider::getName( eObjectType );
+ }
+ return aRet;
+}
+
+OUString ObjectNameProvider::getSelectedObjectText( std::u16string_view rObjectCID, const rtl::Reference<::chart::ChartModel>& xChartDocument )
+{
+ OUString aRet;
+ ObjectType eObjectType( ObjectIdentifier::getObjectType(rObjectCID) );
+
+ if( eObjectType == OBJECTTYPE_DATA_POINT )
+ {
+ aRet = SchResId( STR_STATUS_DATAPOINT_MARKED );
+
+ rtl::Reference< Diagram > xDiagram( xChartDocument->getFirstChartDiagram() );
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartDocument );
+ if( xDiagram.is() && xSeries.is() )
+ {
+ sal_Int32 nPointIndex = o3tl::toInt32( ObjectIdentifier::getParticleID(rObjectCID) );
+
+ // replace data point index
+ replaceParamterInString( aRet, u"%POINTNUMBER", OUString::number( nPointIndex + 1 ));
+
+ // replace data series index
+ {
+ std::vector< rtl::Reference< DataSeries > > aSeriesVector(
+ xDiagram->getDataSeries() );
+ sal_Int32 nSeriesIndex = -1;
+ for( nSeriesIndex=aSeriesVector.size();nSeriesIndex--;)
+ {
+ if( aSeriesVector[nSeriesIndex] == xSeries )
+ break;
+ }
+ replaceParamterInString( aRet, u"%SERIESNUMBER", OUString::number( nSeriesIndex + 1 ) );
+ }
+
+ // replace point value
+ replaceParamterInString( aRet, u"%POINTVALUES", lcl_getDataPointValueText(
+ xSeries, nPointIndex, DataSeriesHelper::getCoordinateSystemOfSeries(xSeries, xDiagram), xChartDocument ) );
+ }
+ }
+ else
+ {
+ // use the verbose text including the formula for trend lines
+ const bool bVerbose( eObjectType == OBJECTTYPE_DATA_CURVE || eObjectType == OBJECTTYPE_DATA_AVERAGE_LINE );
+ const OUString aHelpText( getHelpText( rObjectCID, xChartDocument, bVerbose ));
+ if( !aHelpText.isEmpty())
+ {
+ aRet = SchResId( STR_STATUS_OBJECT_MARKED );
+ replaceParamterInString( aRet, u"%OBJECTNAME", aHelpText );
+ }
+ }
+
+ return aRet;
+}
+
+OUString ObjectNameProvider::getNameForCID(
+ std::u16string_view rObjectCID,
+ const rtl::Reference<::chart::ChartModel>& xChartDocument )
+{
+ ObjectType eType( ObjectIdentifier::getObjectType( rObjectCID ));
+
+ switch( eType )
+ {
+ case OBJECTTYPE_AXIS:
+ return getAxisName( rObjectCID, xChartDocument );
+ case OBJECTTYPE_TITLE:
+ return getTitleName( rObjectCID, xChartDocument );
+ case OBJECTTYPE_GRID:
+ case OBJECTTYPE_SUBGRID:
+ return getGridName( rObjectCID, xChartDocument );
+ case OBJECTTYPE_DATA_SERIES:
+ return lcl_getFullSeriesName( rObjectCID, xChartDocument );
+ case OBJECTTYPE_DATA_POINT:
+ case OBJECTTYPE_DATA_LABELS:
+ case OBJECTTYPE_DATA_LABEL:
+ case OBJECTTYPE_DATA_ERRORS_X:
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ case OBJECTTYPE_DATA_CURVE:
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ {
+ OUString aRet = lcl_getFullSeriesName( rObjectCID, xChartDocument ) + " ";
+ if( eType == OBJECTTYPE_DATA_POINT || eType == OBJECTTYPE_DATA_LABEL )
+ {
+ aRet += getName( OBJECTTYPE_DATA_POINT );
+ sal_Int32 nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
+ aRet += " " + OUString::number(nPointIndex+1);
+ if( eType == OBJECTTYPE_DATA_LABEL )
+ {
+ aRet += " " + getName( OBJECTTYPE_DATA_LABEL );
+ }
+ }
+ else if (eType == OBJECTTYPE_DATA_CURVE || eType == OBJECTTYPE_DATA_CURVE_EQUATION)
+ {
+ rtl::Reference< DataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( rObjectCID , xChartDocument ));
+
+ aRet += " " + getName(eType);
+
+ if( xSeries.is())
+ {
+ sal_Int32 nCurveIndex = ObjectIdentifier::getIndexFromParticleOrCID( rObjectCID );
+ rtl::Reference< RegressionCurveModel > xCurve( RegressionCurveHelper::getRegressionCurveAtIndex(xSeries, nCurveIndex) );
+ if( xCurve.is())
+ {
+ aRet += " (" + RegressionCurveHelper::getRegressionCurveName(xCurve) + ")";
+ }
+ }
+ }
+ else
+ {
+ aRet += getName( eType );
+ }
+ return aRet;
+ }
+ default:
+ break;
+ }
+
+ return getName( eType );
+}
+
+OUString ObjectNameProvider::getName_ObjectForSeries(
+ ObjectType eObjectType,
+ std::u16string_view rSeriesCID,
+ const rtl::Reference<::chart::ChartModel>& xChartDocument )
+{
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rSeriesCID , xChartDocument );
+ if( xSeries.is() )
+ {
+ OUString aRet = SchResId(STR_OBJECT_FOR_SERIES);
+ replaceParamterInString( aRet, u"%OBJECTNAME", getName( eObjectType ) );
+ replaceParamterInString( aRet, u"%SERIESNAME", lcl_getDataSeriesName( rSeriesCID, xChartDocument ) );
+ return aRet;
+ }
+ else
+ return ObjectNameProvider::getName_ObjectForAllSeries( eObjectType );
+}
+
+OUString ObjectNameProvider::getName_ObjectForAllSeries( ObjectType eObjectType )
+{
+ OUString aRet = SchResId(STR_OBJECT_FOR_ALL_SERIES);
+ replaceParamterInString( aRet, u"%OBJECTNAME", getName( eObjectType, true /*bPlural*/ ) );
+ return aRet;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/RangeSelectionHelper.cxx b/chart2/source/controller/dialogs/RangeSelectionHelper.cxx
new file mode 100644
index 0000000000..00e9a3cc8a
--- /dev/null
+++ b/chart2/source/controller/dialogs/RangeSelectionHelper.cxx
@@ -0,0 +1,178 @@
+/* -*- 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 .
+ */
+
+#include <RangeSelectionHelper.hxx>
+#include <RangeSelectionListener.hxx>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <ChartModel.hxx>
+#include <utility>
+
+using namespace ::com::sun::star;
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+
+namespace chart
+{
+
+RangeSelectionHelper::RangeSelectionHelper(
+ rtl::Reference<::chart::ChartModel> xChartDocument ) :
+ m_xChartDocument(std::move( xChartDocument ))
+{}
+
+RangeSelectionHelper::~RangeSelectionHelper()
+{}
+
+bool RangeSelectionHelper::hasRangeSelection()
+{
+ return getRangeSelection().is();
+}
+
+Reference< sheet::XRangeSelection > const & RangeSelectionHelper::getRangeSelection()
+{
+ if( !m_xRangeSelection.is() &&
+ m_xChartDocument.is() )
+ {
+ try
+ {
+ Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
+ if( xDataProvider.is())
+ m_xRangeSelection.set( xDataProvider->getRangeSelection());
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+
+ m_xRangeSelection.clear();
+ }
+ }
+
+ return m_xRangeSelection;
+}
+
+void RangeSelectionHelper::raiseRangeSelectionDocument()
+{
+ Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
+ if( !xRangeSel.is())
+ return;
+
+ try
+ {
+ // bring document to front
+ Reference< frame::XController > xCtrl( xRangeSel, uno::UNO_QUERY );
+ if( xCtrl.is())
+ {
+ Reference< frame::XFrame > xFrame( xCtrl->getFrame());
+ if( xFrame.is())
+ {
+ Reference< awt::XTopWindow > xWin( xFrame->getContainerWindow(),
+ uno::UNO_QUERY_THROW );
+ xWin->toFront();
+ }
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+bool RangeSelectionHelper::chooseRange(
+ const OUString & aCurrentRange,
+ const OUString & aUIString,
+ RangeSelectionListenerParent & rListenerParent )
+{
+ ControllerLockGuardUNO aGuard( m_xChartDocument );
+
+ bool bResult = true;
+ raiseRangeSelectionDocument();
+
+ try
+ {
+ Reference< sheet::XRangeSelection > xRangeSel( getRangeSelection());
+ if( xRangeSel.is())
+ {
+ Sequence< beans::PropertyValue > aArgs{
+ beans::PropertyValue(
+ "InitialValue", -1, uno::Any( aCurrentRange ),
+ beans::PropertyState_DIRECT_VALUE ),
+ beans::PropertyValue(
+ "Title", -1,
+ uno::Any( aUIString ),
+ beans::PropertyState_DIRECT_VALUE ),
+ beans::PropertyValue(
+ "CloseOnMouseRelease", -1, uno::Any( true ),
+ beans::PropertyState_DIRECT_VALUE ),
+ beans::PropertyValue(
+ "MultiSelectionMode", -1, uno::Any( true ),
+ beans::PropertyState_DIRECT_VALUE )
+ };
+ if( m_xRangeSelectionListener.is() )
+ stopRangeListening();
+ m_xRangeSelectionListener.set( Reference< sheet::XRangeSelectionListener >(
+ new RangeSelectionListener( rListenerParent, aCurrentRange, m_xChartDocument )));
+
+ xRangeSel->addRangeSelectionListener( m_xRangeSelectionListener );
+ xRangeSel->startRangeSelection( aArgs );
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ bResult = false;
+ }
+
+ return bResult;
+}
+
+void RangeSelectionHelper::stopRangeListening( bool bRemoveListener /* = true */ )
+{
+ if( bRemoveListener &&
+ m_xRangeSelectionListener.is() &&
+ m_xRangeSelection.is() )
+ {
+ m_xRangeSelection->removeRangeSelectionListener( m_xRangeSelectionListener );
+ }
+
+ m_xRangeSelectionListener = nullptr;
+}
+
+bool RangeSelectionHelper::verifyCellRange( const OUString & rRangeStr )
+{
+ Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
+ if( ! xDataProvider.is())
+ return false;
+
+ return xDataProvider->createDataSequenceByRangeRepresentationPossible( rRangeStr );
+}
+
+bool RangeSelectionHelper::verifyArguments( const Sequence< beans::PropertyValue > & rArguments )
+{
+ Reference< chart2::data::XDataProvider > xDataProvider( m_xChartDocument->getDataProvider());
+ if( ! xDataProvider.is())
+ return false;
+
+ return xDataProvider->createDataSourcePossible( rArguments );
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/RangeSelectionListener.cxx b/chart2/source/controller/dialogs/RangeSelectionListener.cxx
new file mode 100644
index 0000000000..e4974ab30d
--- /dev/null
+++ b/chart2/source/controller/dialogs/RangeSelectionListener.cxx
@@ -0,0 +1,61 @@
+/* -*- 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 .
+ */
+
+#include <RangeSelectionListener.hxx>
+#include <ChartModel.hxx>
+#include <utility>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+RangeSelectionListener::RangeSelectionListener(
+ RangeSelectionListenerParent & rParent,
+ OUString aInitialRange,
+ const rtl::Reference<::chart::ChartModel>& xModelToLockController ) :
+ m_rParent( rParent ),
+ m_aRange(std::move( aInitialRange )),
+ m_aControllerLockGuard( xModelToLockController )
+{}
+
+RangeSelectionListener::~RangeSelectionListener()
+{}
+
+// ____ XRangeSelectionListener ____
+void SAL_CALL RangeSelectionListener::done( const sheet::RangeSelectionEvent& aEvent )
+{
+ m_aRange = aEvent.RangeDescriptor;
+ m_rParent.listeningFinished( m_aRange );
+}
+
+void SAL_CALL RangeSelectionListener::aborted( const sheet::RangeSelectionEvent& /*aEvent*/ )
+{
+ m_rParent.listeningFinished( m_aRange );
+}
+
+// ____ XEventListener ____
+void SAL_CALL RangeSelectionListener::disposing( const lang::EventObject& /*Source*/ )
+{
+ m_rParent.disposingRangeSelection();
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/TextDirectionListBox.cxx b/chart2/source/controller/dialogs/TextDirectionListBox.cxx
new file mode 100644
index 0000000000..68181fdfc7
--- /dev/null
+++ b/chart2/source/controller/dialogs/TextDirectionListBox.cxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+
+#include <TextDirectionListBox.hxx>
+#include <ResId.hxx>
+#include <strings.hrc>
+
+namespace chart
+{
+TextDirectionListBox::TextDirectionListBox(std::unique_ptr<weld::ComboBox> pControl)
+ : svx::FrameDirectionListBox(std::move(pControl))
+{
+ append(SvxFrameDirection::Horizontal_LR_TB, SchResId(STR_TEXT_DIRECTION_LTR));
+ append(SvxFrameDirection::Horizontal_RL_TB, SchResId(STR_TEXT_DIRECTION_RTL));
+ append(SvxFrameDirection::Environment, SchResId(STR_TEXT_DIRECTION_SUPER));
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/TimerTriggeredControllerLock.cxx b/chart2/source/controller/dialogs/TimerTriggeredControllerLock.cxx
new file mode 100644
index 0000000000..cee4af1fb0
--- /dev/null
+++ b/chart2/source/controller/dialogs/TimerTriggeredControllerLock.cxx
@@ -0,0 +1,52 @@
+/* -*- 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 .
+ */
+
+#include <TimerTriggeredControllerLock.hxx>
+#include <ControllerLockGuard.hxx>
+#include <ChartModel.hxx>
+#include <utility>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+
+TimerTriggeredControllerLock::TimerTriggeredControllerLock(
+ rtl::Reference<::chart::ChartModel> xModel)
+ : m_xModel(std::move(xModel))
+ , m_aTimer("chart2 TimerTriggeredControllerLock")
+{
+ m_aTimer.SetTimeout(4 * EDIT_UPDATEDATA_TIMEOUT);
+ m_aTimer.SetInvokeHandler(LINK(this, TimerTriggeredControllerLock, TimerTimeout));
+}
+TimerTriggeredControllerLock::~TimerTriggeredControllerLock() { m_aTimer.Stop(); }
+
+void TimerTriggeredControllerLock::startTimer()
+{
+ if (!m_apControllerLockGuard)
+ m_apControllerLockGuard.reset(new ControllerLockGuardUNO(m_xModel));
+ m_aTimer.Start();
+}
+IMPL_LINK_NOARG(TimerTriggeredControllerLock, TimerTimeout, Timer*, void)
+{
+ m_apControllerLockGuard.reset();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/TitleDialogData.cxx b/chart2/source/controller/dialogs/TitleDialogData.cxx
new file mode 100644
index 0000000000..f110b3d520
--- /dev/null
+++ b/chart2/source/controller/dialogs/TitleDialogData.cxx
@@ -0,0 +1,113 @@
+/* -*- 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 .
+ */
+
+#include <sal/config.h>
+
+#include <TitleDialogData.hxx>
+#include <TitleHelper.hxx>
+#include <ChartModelHelper.hxx>
+#include <Diagram.hxx>
+#include <AxisHelper.hxx>
+#include <ChartModel.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+TitleDialogData::TitleDialogData( std::unique_ptr<ReferenceSizeProvider> pRefSizeProvider )
+ : aPossibilityList{ true, true, true, true, true, true, true }
+ , aExistenceList{ false, false, false, false, false, false, false }
+ , aTextList(7)
+ , apReferenceSizeProvider( std::move(pRefSizeProvider) )
+{
+}
+
+void TitleDialogData::readFromModel( const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
+
+ //get possibilities
+ uno::Sequence< sal_Bool > aAxisPossibilityList;
+ AxisHelper::getAxisOrGridPossibilities( aAxisPossibilityList, xDiagram );
+ sal_Bool* pPossibilityList = aPossibilityList.getArray();
+ pPossibilityList[2]=aAxisPossibilityList[0];//x axis title
+ pPossibilityList[3]=aAxisPossibilityList[1];//y axis title
+ pPossibilityList[4]=aAxisPossibilityList[2];//z axis title
+ pPossibilityList[5]=aAxisPossibilityList[3];//secondary x axis title
+ pPossibilityList[6]=aAxisPossibilityList[4];//secondary y axis title
+
+ sal_Bool* pExistenceList = aExistenceList.getArray();
+ auto pTextList = aTextList.getArray();
+ //find out which title exists and get their text
+ //main title:
+ for( auto nTitleIndex = +TitleHelper::TITLE_BEGIN;
+ nTitleIndex < +TitleHelper::NORMAL_TITLE_END;
+ nTitleIndex++)
+ {
+ rtl::Reference< Title > xTitle = TitleHelper::getTitle(
+ static_cast< TitleHelper::eTitleType >( nTitleIndex ), xChartModel );
+ pExistenceList[nTitleIndex] = xTitle.is();
+ pTextList[nTitleIndex]=TitleHelper::getCompleteString( xTitle );
+ }
+}
+
+bool TitleDialogData::writeDifferenceToModel(
+ const rtl::Reference<::chart::ChartModel>& xChartModel
+ , const uno::Reference< uno::XComponentContext >& xContext
+ , const TitleDialogData* pOldState )
+{
+ bool bChanged = false;
+ for( auto nN = +TitleHelper::TITLE_BEGIN;
+ nN < +TitleHelper::NORMAL_TITLE_END;
+ nN++)
+ {
+ if( !pOldState || ( pOldState->aExistenceList[nN] != aExistenceList[nN] ) )
+ {
+ if(aExistenceList[nN])
+ {
+ TitleHelper::createTitle(
+ static_cast< TitleHelper::eTitleType >( nN ), aTextList[nN], xChartModel, xContext,
+ apReferenceSizeProvider.get() );
+ bChanged = true;
+ }
+ else
+ {
+ TitleHelper::removeTitle( static_cast< TitleHelper::eTitleType >( nN ), xChartModel );
+ bChanged = true;
+ }
+ }
+ else if( !pOldState || ( pOldState->aTextList[nN] != aTextList[nN] ) )
+ {
+ //change content
+ rtl::Reference< Title > xTitle(
+ TitleHelper::getTitle( static_cast< TitleHelper::eTitleType >( nN ), xChartModel ) );
+ if(xTitle.is())
+ {
+ TitleHelper::setCompleteString( aTextList[nN], xTitle, xContext );
+ bChanged = true;
+ }
+ }
+ }
+ return bChanged;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_ChartType.cxx b/chart2/source/controller/dialogs/dlg_ChartType.cxx
new file mode 100644
index 0000000000..e6e88dae42
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_ChartType.cxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+
+#include <dlg_ChartType.hxx>
+#include "tp_ChartType.hxx"
+#include <ChartModel.hxx>
+#include <utility>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+ChartTypeDialog::ChartTypeDialog(weld::Window* pParent,
+ rtl::Reference<::chart::ChartModel> xChartModel)
+ : GenericDialogController(pParent, "modules/schart/ui/charttypedialog.ui", "ChartTypeDialog")
+ , m_xChartModel(std::move(xChartModel))
+ , m_xContentArea(m_xBuilder->weld_container("content"))
+{
+ m_xChartTypeTabPage = std::make_unique<ChartTypeTabPage>(
+ m_xContentArea.get(), this, m_xChartModel, false /*don't show title description*/);
+
+ m_xChartTypeTabPage->initializePage();
+}
+
+ChartTypeDialog::~ChartTypeDialog() { m_xChartTypeTabPage.reset(); }
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_ChartType_UNO.cxx b/chart2/source/controller/dialogs/dlg_ChartType_UNO.cxx
new file mode 100644
index 0000000000..0e95cd75c4
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_ChartType_UNO.cxx
@@ -0,0 +1,113 @@
+/* -*- 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 .
+ */
+
+#include <dlg_ChartType_UNO.hxx>
+#include <dlg_ChartType.hxx>
+#include <ChartModel.hxx>
+#include <servicenames.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+namespace com::sun::star::awt { class XWindow; }
+
+namespace chart
+{
+using namespace ::com::sun::star;
+ChartTypeUnoDlg::ChartTypeUnoDlg( const uno::Reference< uno::XComponentContext >& _xContext )
+ : ChartTypeUnoDlg_BASE( _xContext )
+{
+}
+ChartTypeUnoDlg::~ChartTypeUnoDlg()
+{
+ // we do this here cause the base class' call to destroyDialog won't reach us anymore: we're within a dtor,
+ // so this virtual-method-call the base class does not work, we're already dead then...
+ if (m_xDialog)
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ if (m_xDialog)
+ destroyDialog();
+ }
+}
+// lang::XServiceInfo
+OUString SAL_CALL ChartTypeUnoDlg::getImplementationName()
+{
+ return CHART_TYPE_DIALOG_SERVICE_IMPLEMENTATION_NAME;
+}
+
+css::uno::Sequence<OUString> SAL_CALL ChartTypeUnoDlg::getSupportedServiceNames()
+{
+ return { CHART_TYPE_DIALOG_SERVICE_NAME };
+}
+uno::Sequence< sal_Int8 > SAL_CALL ChartTypeUnoDlg::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+void ChartTypeUnoDlg::implInitialize(const uno::Any& _rValue)
+{
+ beans::PropertyValue aProperty;
+ if (_rValue >>= aProperty)
+ {
+ if (aProperty.Name == "ChartModel")
+ {
+ uno::Reference<XInterface> xInt;
+ aProperty.Value >>= xInt;
+ assert(dynamic_cast<::chart::ChartModel*>(xInt.get()));
+ m_xChartModel = dynamic_cast<::chart::ChartModel*>(xInt.get());
+ }
+ else
+ ChartTypeUnoDlg_BASE::implInitialize(_rValue);
+ }
+ else
+ ChartTypeUnoDlg_BASE::implInitialize(_rValue);
+}
+
+std::unique_ptr<weld::DialogController> ChartTypeUnoDlg::createDialog(const css::uno::Reference<css::awt::XWindow>& rParent)
+{
+ ChartModel* pChartModel = dynamic_cast<ChartModel*>(rParent.get());
+ assert(pChartModel);
+ return std::make_unique<ChartTypeDialog>(Application::GetFrameWeld(rParent), pChartModel);
+}
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ChartTypeUnoDlg::getPropertySetInfo()
+{
+ return createPropertySetInfo( getInfoHelper() );
+}
+
+::cppu::IPropertyArrayHelper& ChartTypeUnoDlg::getInfoHelper()
+{
+ return *getArrayHelper();
+}
+
+::cppu::IPropertyArrayHelper* ChartTypeUnoDlg::createArrayHelper( ) const
+{
+ uno::Sequence< beans::Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+}
+
+} //namespace chart
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_chart2_ChartTypeDialog_get_implementation(css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new chart::ChartTypeUnoDlg(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_CreationWizard.cxx b/chart2/source/controller/dialogs/dlg_CreationWizard.cxx
new file mode 100644
index 0000000000..12d2280579
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_CreationWizard.cxx
@@ -0,0 +1,202 @@
+/* -*- 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 .
+ */
+
+#include <dlg_CreationWizard.hxx>
+#include <ResId.hxx>
+#include <strings.hrc>
+#include <helpids.h>
+#include <ChartModel.hxx>
+
+#include "tp_ChartType.hxx"
+#include "tp_RangeChooser.hxx"
+#include "tp_Wizard_TitlesAndObjects.hxx"
+#include "tp_DataSource.hxx"
+#include <ChartTypeTemplateProvider.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <utility>
+#include "DialogModel.hxx"
+
+using namespace css;
+
+using vcl::RoadmapWizardTypes::WizardPath;
+
+namespace chart
+{
+#define PATH_FULL 1
+#define STATE_FIRST 0
+#define STATE_CHARTTYPE STATE_FIRST
+#define STATE_SIMPLE_RANGE 1
+#define STATE_DATA_SERIES 2
+#define STATE_OBJECTS 3
+#define STATE_LAST STATE_OBJECTS
+
+CreationWizard::CreationWizard(weld::Window* pParent, const rtl::Reference<::chart::ChartModel>& xChartModel,
+ uno::Reference<uno::XComponentContext> xContext)
+ : vcl::RoadmapWizardMachine(pParent)
+ , m_xChartModel(xChartModel,uno::UNO_QUERY)
+ , m_xComponentContext(std::move(xContext))
+ , m_pTemplateProvider(nullptr)
+ , m_aTimerTriggeredControllerLock(xChartModel)
+ , m_bCanTravel(true)
+{
+ m_pDialogModel.reset(new DialogModel(m_xChartModel));
+ defaultButton(WizardButtonFlags::FINISH);
+
+ setTitleBase(SchResId(STR_DLG_CHART_WIZARD));
+
+ // tdf#134386 set m_pTemplateProvider before creating any other pages
+ m_pTemplateProvider = static_cast<ChartTypeTabPage*>(GetOrCreatePage(STATE_CHARTTYPE));
+ assert(m_pTemplateProvider && "must exist");
+ m_pDialogModel->setTemplate(m_pTemplateProvider->getCurrentTemplate());
+
+ WizardPath aPath = {
+ STATE_CHARTTYPE,
+ STATE_SIMPLE_RANGE,
+ STATE_DATA_SERIES,
+ STATE_OBJECTS
+ };
+
+ declarePath(PATH_FULL, aPath);
+
+ // tdf#135935 ensure help ID is set when no element is clicked in the dialog
+ m_xAssistant->set_help_id(HID_SCH_WIZARD_ROADMAP);
+
+ if (!m_pDialogModel->getModel().isDataFromSpreadsheet())
+ {
+ enableState(STATE_SIMPLE_RANGE, false);
+ enableState(STATE_DATA_SERIES, false);
+ }
+
+ // Call ActivatePage, to create and activate the first page
+ ActivatePage();
+
+ m_xAssistant->set_current_page(0);
+}
+
+CreationWizard::~CreationWizard() = default;
+
+std::unique_ptr<BuilderPage> CreationWizard::createPage(WizardState nState)
+{
+ std::unique_ptr<vcl::OWizardPage> xRet;
+
+ OUString sIdent(OUString::number(nState));
+ weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
+
+ switch( nState )
+ {
+ case STATE_CHARTTYPE:
+ {
+ m_aTimerTriggeredControllerLock.startTimer();
+ xRet = std::make_unique<ChartTypeTabPage>(pPageContainer, this, m_xChartModel);
+ break;
+ }
+ case STATE_SIMPLE_RANGE:
+ {
+ m_aTimerTriggeredControllerLock.startTimer();
+ xRet = std::make_unique<RangeChooserTabPage>(pPageContainer, this, *m_pDialogModel, m_pTemplateProvider);
+ break;
+ }
+ case STATE_DATA_SERIES:
+ {
+ m_aTimerTriggeredControllerLock.startTimer();
+ xRet = std::make_unique<DataSourceTabPage>(pPageContainer, this, *m_pDialogModel, m_pTemplateProvider);
+ break;
+ }
+ case STATE_OBJECTS:
+ {
+ xRet = std::make_unique<TitlesAndObjectsTabPage>(pPageContainer, this, m_xChartModel, m_xComponentContext);
+ m_aTimerTriggeredControllerLock.startTimer();
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (xRet)
+ xRet->SetPageTitle(OUString()); //remove title of pages to not get them in the wizard title
+
+ return xRet;
+}
+
+bool CreationWizard::leaveState( WizardState /*_nState*/ )
+{
+ return m_bCanTravel;
+}
+
+vcl::WizardTypes::WizardState CreationWizard::determineNextState( WizardState nCurrentState ) const
+{
+ if( !m_bCanTravel )
+ return WZS_INVALID_STATE;
+ if( nCurrentState == STATE_LAST )
+ return WZS_INVALID_STATE;
+ vcl::WizardTypes::WizardState nNextState = nCurrentState + 1;
+ while( !isStateEnabled( nNextState ) && nNextState <= STATE_LAST )
+ ++nNextState;
+ return (nNextState==STATE_LAST+1) ? WZS_INVALID_STATE : nNextState;
+}
+
+void CreationWizard::enterState(WizardState nState)
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ enableButtons( WizardButtonFlags::PREVIOUS, nState > STATE_FIRST );
+ enableButtons( WizardButtonFlags::NEXT, nState < STATE_LAST );
+ if( isStateEnabled( nState ))
+ vcl::RoadmapWizardMachine::enterState(nState);
+}
+
+void CreationWizard::setInvalidPage(BuilderPage* pTabPage)
+{
+ if (pTabPage == m_pCurTabPage)
+ m_bCanTravel = false;
+}
+
+void CreationWizard::setValidPage(BuilderPage* pTabPage)
+{
+ if (pTabPage == m_pCurTabPage)
+ m_bCanTravel = true;
+}
+
+OUString CreationWizard::getStateDisplayName( WizardState nState ) const
+{
+ TranslateId pResId;
+ switch( nState )
+ {
+ case STATE_CHARTTYPE:
+ pResId = STR_PAGE_CHARTTYPE;
+ break;
+ case STATE_SIMPLE_RANGE:
+ pResId = STR_PAGE_DATA_RANGE;
+ break;
+ case STATE_DATA_SERIES:
+ pResId = STR_OBJECT_DATASERIES_PLURAL;
+ break;
+ case STATE_OBJECTS:
+ pResId = STR_PAGE_CHART_ELEMENTS;
+ break;
+ default:
+ break;
+ }
+ if (!pResId)
+ return OUString();
+ return SchResId(pResId);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_CreationWizard_UNO.cxx b/chart2/source/controller/dialogs/dlg_CreationWizard_UNO.cxx
new file mode 100644
index 0000000000..3a1fa1386f
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_CreationWizard_UNO.cxx
@@ -0,0 +1,362 @@
+/* -*- 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 .
+ */
+
+#include <dlg_CreationWizard_UNO.hxx>
+#include <dlg_CreationWizard.hxx>
+#include <ChartModel.hxx>
+#include <servicenames.hxx>
+#include <TimerTriggeredControllerLock.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <sfx2/viewsh.hxx>
+
+
+namespace chart
+{
+using namespace ::com::sun::star;
+
+CreationWizardUnoDlg::CreationWizardUnoDlg(uno::Reference<uno::XComponentContext> xContext)
+ : OComponentHelper(m_aMutex)
+ , m_xCC(std::move(xContext))
+ , m_bUnlockControllersOnExecute(false)
+{
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(m_xCC);
+ uno::Reference< frame::XTerminateListener > xListener( this );
+ xDesktop->addTerminateListener( xListener );
+}
+
+CreationWizardUnoDlg::~CreationWizardUnoDlg()
+{
+ SolarMutexGuard aSolarGuard;
+ m_xDialog.reset();
+}
+
+// lang::XServiceInfo
+OUString SAL_CALL CreationWizardUnoDlg::getImplementationName()
+{
+ return CHART_WIZARD_DIALOG_SERVICE_IMPLEMENTATION_NAME;
+}
+
+sal_Bool SAL_CALL CreationWizardUnoDlg::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence< OUString > SAL_CALL CreationWizardUnoDlg::getSupportedServiceNames()
+{
+ return { CHART_WIZARD_DIALOG_SERVICE_NAME };
+}
+
+// XInterface
+uno::Any SAL_CALL CreationWizardUnoDlg::queryInterface( const uno::Type& aType )
+{
+ return OComponentHelper::queryInterface( aType );
+}
+void SAL_CALL CreationWizardUnoDlg::acquire() noexcept
+{
+ OComponentHelper::acquire();
+}
+void SAL_CALL CreationWizardUnoDlg::release() noexcept
+{
+ OComponentHelper::release();
+}
+uno::Any SAL_CALL CreationWizardUnoDlg::queryAggregation( uno::Type const & rType )
+{
+ if (rType == cppu::UnoType<ui::dialogs::XAsynchronousExecutableDialog>::get())
+ {
+ void * p = static_cast< ui::dialogs::XAsynchronousExecutableDialog * >( this );
+ return uno::Any( &p, rType );
+ }
+ else if (rType == cppu::UnoType<lang::XServiceInfo>::get())
+ {
+ void * p = static_cast< lang::XServiceInfo * >( this );
+ return uno::Any( &p, rType );
+ }
+ else if (rType == cppu::UnoType<lang::XInitialization>::get())
+ {
+ void * p = static_cast< lang::XInitialization * >( this );
+ return uno::Any( &p, rType );
+ }
+ else if (rType == cppu::UnoType<frame::XTerminateListener>::get())
+ {
+ void * p = static_cast< frame::XTerminateListener * >( this );
+ return uno::Any( &p, rType );
+ }
+ else if (rType == cppu::UnoType<beans::XPropertySet>::get())
+ {
+ void * p = static_cast< beans::XPropertySet * >( this );
+ return uno::Any( &p, rType );
+ }
+ return OComponentHelper::queryAggregation( rType );
+}
+
+uno::Sequence< uno::Type > CreationWizardUnoDlg::getTypes()
+{
+ static uno::Sequence<uno::Type> aTypeList{ cppu::UnoType<lang::XComponent>::get(),
+ cppu::UnoType<lang::XTypeProvider>::get(),
+ cppu::UnoType<uno::XAggregation>::get(),
+ cppu::UnoType<uno::XWeak>::get(),
+ cppu::UnoType<lang::XServiceInfo>::get(),
+ cppu::UnoType<lang::XInitialization>::get(),
+ cppu::UnoType<frame::XTerminateListener>::get(),
+ cppu::UnoType<ui::dialogs::XAsynchronousExecutableDialog>::get(),
+ cppu::UnoType<beans::XPropertySet>::get() };
+ return aTypeList;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL CreationWizardUnoDlg::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// XTerminateListener
+void SAL_CALL CreationWizardUnoDlg::queryTermination( const lang::EventObject& /*Event*/ )
+{
+}
+
+void SAL_CALL CreationWizardUnoDlg::notifyTermination( const lang::EventObject& /*Event*/ )
+{
+ // we are going down, so dispose us!
+ dispose();
+}
+
+void SAL_CALL CreationWizardUnoDlg::disposing( const lang::EventObject& /*Source*/ )
+{
+ //Listener should deregister himself and release all references to the closing object.
+}
+
+void SAL_CALL CreationWizardUnoDlg::setDialogTitle( const OUString& /*rTitle*/ )
+{
+}
+void CreationWizardUnoDlg::createDialogOnDemand()
+{
+ SolarMutexGuard aSolarGuard;
+ if (m_xDialog)
+ return;
+
+ if( !m_xParentWindow.is() && m_xChartModel.is() )
+ {
+ uno::Reference< frame::XController > xController(
+ m_xChartModel->getCurrentController() );
+ if( xController.is() )
+ {
+ uno::Reference< frame::XFrame > xFrame(
+ xController->getFrame() );
+ if(xFrame.is())
+ m_xParentWindow = xFrame->getContainerWindow();
+ }
+ }
+
+ weld::Window* pParent(Application::GetFrameWeld(m_xParentWindow));
+ if (!pParent)
+ {
+ if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(m_xParentWindow.get()))
+ pParent = dynamic_cast<weld::Window*>(pTunnel->getWidget());
+ }
+
+ uno::Reference< XComponent > xKeepAlive( this );
+ if( m_xChartModel.is() )
+ {
+ m_xDialog = std::make_shared<CreationWizard>(pParent, m_xChartModel, m_xCC);
+ }
+}
+
+IMPL_STATIC_LINK_NOARG(CreationWizardUnoDlg, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*)
+{
+ return SfxViewShell::Current();
+}
+
+void SAL_CALL CreationWizardUnoDlg::startExecuteModal( const css::uno::Reference<css::ui::dialogs::XDialogClosedListener>& xListener )
+{
+ SolarMutexGuard aSolarGuard;
+ createDialogOnDemand();
+
+ if( !m_xDialog )
+ return;
+
+ m_xDialog->getDialog()->SetInstallLOKNotifierHdl(
+ LINK(this, CreationWizardUnoDlg, InstallLOKNotifierHdl));
+
+ TimerTriggeredControllerLock aTimerTriggeredControllerLock( m_xChartModel );
+ if( m_bUnlockControllersOnExecute && m_xChartModel.is() )
+ m_xChartModel->unlockControllers();
+
+ CreationWizardUnoDlg* xThat = this;
+ weld::DialogController::runAsync(m_xDialog, [xListener, xThat](sal_Int32 nResult){
+ if( xListener.is() )
+ {
+ ::css::uno::Reference< ::css::uno::XInterface > xSource;
+ // Notify UNO listener to perform correct action depending on the result
+ css::ui::dialogs::DialogClosedEvent aEvent( xSource, nResult );
+ xListener->dialogClosed( aEvent );
+ }
+ xThat->m_xDialog.reset();
+ });
+}
+
+void SAL_CALL CreationWizardUnoDlg::initialize( const uno::Sequence< uno::Any >& aArguments )
+{
+ for(const uno::Any& rArgument : aArguments)
+ {
+ beans::PropertyValue aProperty;
+ if(rArgument >>= aProperty)
+ {
+ if( aProperty.Name == "ParentWindow" )
+ {
+ aProperty.Value >>= m_xParentWindow;
+ }
+ else if( aProperty.Name == "ChartModel" )
+ {
+ uno::Reference<XInterface> xInt;
+ aProperty.Value >>= xInt;
+ m_xChartModel = dynamic_cast<::chart::ChartModel*>(xInt.get());
+ assert(m_xChartModel);
+ }
+ }
+ }
+}
+
+// ____ OComponentHelper ____
+/// Called in dispose method after the listeners were notified.
+void SAL_CALL CreationWizardUnoDlg::disposing()
+{
+ m_xChartModel.clear();
+ m_xParentWindow.clear();
+
+ SolarMutexGuard aSolarGuard;
+ m_xDialog.reset();
+
+ try
+ {
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(m_xCC);
+ uno::Reference< frame::XTerminateListener > xListener( this );
+ xDesktop->removeTerminateListener( xListener );
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+//XPropertySet
+uno::Reference< beans::XPropertySetInfo > SAL_CALL CreationWizardUnoDlg::getPropertySetInfo()
+{
+ OSL_FAIL("not implemented");
+ return nullptr;
+}
+
+void SAL_CALL CreationWizardUnoDlg::setPropertyValue(const OUString& rPropertyName,
+ const uno::Any& rValue)
+{
+ if( rPropertyName == "Position" )
+ {
+ SolarMutexGuard aSolarGuard;
+ createDialogOnDemand();
+
+ //read only property, do nothing else
+ }
+ else if( rPropertyName == "Size")
+ {
+ //read only property, do nothing
+ }
+ else if( rPropertyName == "UnlockControllersOnExecute" )
+ {
+ if( ! (rValue >>= m_bUnlockControllersOnExecute) )
+ throw lang::IllegalArgumentException( "Property 'UnlockControllers' requires value of type boolean" , nullptr, 0 );
+ }
+ else
+ throw beans::UnknownPropertyException( "unknown property was tried to set to chart wizard" , nullptr );
+}
+
+uno::Any SAL_CALL CreationWizardUnoDlg::getPropertyValue( const OUString& rPropertyName )
+{
+ uno::Any aRet;
+ if( rPropertyName == "Position" )
+ {
+ //get left upper outer corner relative to screen
+ //pixels, screen position
+ SolarMutexGuard aSolarGuard;
+ createDialogOnDemand();
+ if (m_xDialog)
+ {
+ Point aPos(m_xDialog->getDialog()->get_position());
+ awt::Point aPoint(aPos.X(), aPos.Y());
+ aRet <<= aPoint;
+ }
+ }
+ else if( rPropertyName == "Size" )
+ {
+ //get outer size inclusive decoration
+ //pixels, screen position
+ SolarMutexGuard aSolarGuard;
+ createDialogOnDemand();
+ if (m_xDialog)
+ {
+ Size aRect(m_xDialog->getDialog()->get_size());
+ awt::Size aSize(aRect.Width(), aRect.Height());
+ aRet <<= aSize;
+ }
+ }
+ else if( rPropertyName == "UnlockControllersOnExecute" )
+ {
+ aRet <<= m_bUnlockControllersOnExecute;
+ }
+ else
+ throw beans::UnknownPropertyException( "unknown property was tried to get from chart wizard" , nullptr );
+ return aRet;
+}
+
+void SAL_CALL CreationWizardUnoDlg::addPropertyChangeListener(
+ const OUString& /* aPropertyName */, const uno::Reference< beans::XPropertyChangeListener >& /* xListener */ )
+{
+ OSL_FAIL("not implemented");
+}
+void SAL_CALL CreationWizardUnoDlg::removePropertyChangeListener(
+ const OUString& /* aPropertyName */, const uno::Reference< beans::XPropertyChangeListener >& /* aListener */ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL CreationWizardUnoDlg::addVetoableChangeListener( const OUString& /* PropertyName */, const uno::Reference< beans::XVetoableChangeListener >& /* aListener */ )
+{
+ OSL_FAIL("not implemented");
+}
+
+void SAL_CALL CreationWizardUnoDlg::removeVetoableChangeListener( const OUString& /* PropertyName */, const uno::Reference< beans::XVetoableChangeListener >& /* aListener */ )
+{
+ OSL_FAIL("not implemented");
+}
+
+} //namespace chart
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_chart2_WizardDialog_get_implementation(css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new chart::CreationWizardUnoDlg(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_DataEditor.cxx b/chart2/source/controller/dialogs/dlg_DataEditor.cxx
new file mode 100644
index 0000000000..367b1d183a
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_DataEditor.cxx
@@ -0,0 +1,148 @@
+/* -*- 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 .
+ */
+
+#include <dlg_DataEditor.hxx>
+#include "DataBrowser.hxx"
+#include <ChartModel.hxx>
+#include <comphelper/stl_types.hxx>
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <utility>
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
+
+namespace chart
+{
+
+DataEditor::DataEditor(weld::Window* pParent,
+ rtl::Reference<::chart::ChartModel> xChartDoc,
+ const Reference< uno::XComponentContext > & xContext)
+ : GenericDialogController(pParent, "modules/schart/ui/chartdatadialog.ui", "ChartDataDialog")
+ , m_bReadOnly(false)
+ , m_xChartDoc(std::move(xChartDoc))
+ , m_xContext(xContext)
+ , m_xTbxData(m_xBuilder->weld_toolbar("toolbar"))
+ , m_xCloseBtn(m_xBuilder->weld_button("close"))
+ , m_xTable(m_xBuilder->weld_container("datawindow"))
+ , m_xColumns(m_xBuilder->weld_container("columns"))
+ , m_xColors(m_xBuilder->weld_container("colorcolumns"))
+ , m_xTableCtrlParent(m_xTable->CreateChildFrame())
+ , m_xBrwData(VclPtr<DataBrowser>::Create(m_xTableCtrlParent, m_xColumns.get(), m_xColors.get()))
+{
+ m_xCloseBtn->connect_clicked(LINK(this, DataEditor, CloseHdl));
+
+ Size aSize(m_xTable->get_approximate_digit_width() * 75, m_xTable->get_text_height() * 15);
+ m_xTable->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xBrwData->Show();
+
+ m_xTbxData->connect_clicked(LINK(this, DataEditor, ToolboxHdl));
+
+ m_xBrwData->SetCursorMovedHdl( LINK( this, DataEditor, BrowserCursorMovedHdl ));
+
+ m_xBrwData->SetDataFromModel( m_xChartDoc );
+ m_xBrwData->GrabFocus();
+
+ bool bReadOnly = true;
+ if( m_xChartDoc.is())
+ bReadOnly = m_xChartDoc->isReadonly();
+ SetReadOnly( bReadOnly );
+}
+
+DataEditor::~DataEditor()
+{
+ m_xBrwData.disposeAndClear();
+ m_xTableCtrlParent->dispose();
+ m_xTableCtrlParent.clear();
+}
+
+// react on click (or keypress) on toolbar icon
+IMPL_LINK(DataEditor, ToolboxHdl, const OUString&, rId, void)
+{
+ if (rId == "InsertRow")
+ m_xBrwData->InsertRow();
+ else if (rId == "InsertColumn")
+ m_xBrwData->InsertColumn();
+ else if (rId == "InsertTextColumn")
+ m_xBrwData->InsertTextColumn();
+ else if (rId == "RemoveRow")
+ m_xBrwData->RemoveRow();
+ else if (rId == "RemoveColumn")
+ m_xBrwData->RemoveColumn();
+ else if (rId == "MoveLeftColumn")
+ m_xBrwData->MoveLeftColumn();
+ else if (rId == "MoveRightColumn")
+ m_xBrwData->MoveRightColumn();
+ else if (rId == "MoveUpRow")
+ m_xBrwData->MoveUpRow();
+ else if (rId == "MoveDownRow")
+ m_xBrwData->MoveDownRow();
+}
+
+// refresh toolbar icons according to currently selected cell in browse box
+IMPL_LINK_NOARG(DataEditor, BrowserCursorMovedHdl, DataBrowser*, void)
+{
+ if( m_bReadOnly )
+ return;
+
+ bool bIsDataValid = m_xBrwData->IsEnableItem();
+
+ m_xTbxData->set_item_sensitive("InsertRow", bIsDataValid && m_xBrwData->MayInsertRow() );
+ m_xTbxData->set_item_sensitive("InsertColumn", bIsDataValid && m_xBrwData->MayInsertColumn() );
+ m_xTbxData->set_item_sensitive("InsertTextColumn", bIsDataValid && m_xBrwData->MayInsertColumn() );
+ m_xTbxData->set_item_sensitive("RemoveRow", m_xBrwData->MayDeleteRow() );
+ m_xTbxData->set_item_sensitive("RemoveColumn", m_xBrwData->MayDeleteColumn() );
+
+ m_xTbxData->set_item_sensitive("MoveLeftColumn", bIsDataValid && m_xBrwData->MayMoveLeftColumns() );
+ m_xTbxData->set_item_sensitive("MoveRightColumn", bIsDataValid && m_xBrwData->MayMoveRightColumns() );
+ m_xTbxData->set_item_sensitive("MoveDownRow", bIsDataValid && m_xBrwData->MayMoveDownRows() );
+ m_xTbxData->set_item_sensitive("MoveUpRow", bIsDataValid && m_xBrwData->MayMoveUpRows() );
+}
+
+// disable all modifying controls
+void DataEditor::SetReadOnly( bool bReadOnly )
+{
+ m_bReadOnly = bReadOnly;
+ if( m_bReadOnly )
+ {
+ m_xTbxData->set_item_sensitive("InsertRow", false);
+ m_xTbxData->set_item_sensitive("InsertColumn", false);
+ m_xTbxData->set_item_sensitive("InsertTextColumn", false);
+ m_xTbxData->set_item_sensitive("RemoveRow", false);
+ m_xTbxData->set_item_sensitive("RemoveColumn", false);
+ m_xTbxData->set_item_sensitive("MoveLeftColumn", false);
+ m_xTbxData->set_item_sensitive("MoveRightColumn", false);
+ m_xTbxData->set_item_sensitive("MoveUpRow", false);
+ m_xTbxData->set_item_sensitive("MoveDownRow", false);
+ }
+
+ m_xBrwData->SetReadOnly( m_bReadOnly );
+}
+
+IMPL_LINK_NOARG(DataEditor, CloseHdl, weld::Button&, void)
+{
+ bool bApplied = m_xBrwData->EndEditing(); // apply changes to model
+ if (bApplied)
+ m_xDialog->response(RET_CLOSE);
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_DataSource.cxx b/chart2/source/controller/dialogs/dlg_DataSource.cxx
new file mode 100644
index 0000000000..1eb6202deb
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_DataSource.cxx
@@ -0,0 +1,178 @@
+/* -*- 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 .
+ */
+
+#include <com/sun/star/chart2/XChartDocument.hpp>
+
+#include <dlg_DataSource.hxx>
+#include <ChartTypeTemplateProvider.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <Diagram.hxx>
+#include <DiagramHelper.hxx>
+#include "DialogModel.hxx"
+#include <ChartModel.hxx>
+
+#include "tp_RangeChooser.hxx"
+#include "tp_DataSource.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using namespace ::chart;
+
+namespace chart
+{
+
+namespace {
+
+class DocumentChartTypeTemplateProvider : public ChartTypeTemplateProvider
+{
+public:
+ explicit DocumentChartTypeTemplateProvider(
+ const rtl::Reference<::chart::ChartModel> & xDoc );
+
+ // ____ ChartTypeTemplateProvider ____
+ virtual rtl::Reference< ::chart::ChartTypeTemplate > getCurrentTemplate() const override;
+
+private:
+ rtl::Reference< ::chart::ChartTypeTemplate > m_xTemplate;
+};
+
+}
+
+DocumentChartTypeTemplateProvider::DocumentChartTypeTemplateProvider(
+ const rtl::Reference<::chart::ChartModel> & xDoc )
+{
+ if( !xDoc.is())
+ return;
+
+ rtl::Reference< Diagram > xDia( xDoc->getFirstChartDiagram());
+ if( xDia.is())
+ {
+ Diagram::tTemplateWithServiceName aResult(
+ xDia->getTemplate( xDoc->getTypeManager() ));
+ m_xTemplate = aResult.xChartTypeTemplate;
+ }
+}
+
+rtl::Reference< ::chart::ChartTypeTemplate > DocumentChartTypeTemplateProvider::getCurrentTemplate() const
+{
+ return m_xTemplate;
+}
+
+sal_uInt16 DataSourceDialog::m_nLastPageId = 0;
+
+DataSourceDialog::DataSourceDialog(weld::Window * pParent,
+ const rtl::Reference<::chart::ChartModel> & xChartDocument)
+ : GenericDialogController(pParent, "modules/schart/ui/datarangedialog.ui",
+ "DataRangeDialog")
+ , m_apDocTemplateProvider(new DocumentChartTypeTemplateProvider(xChartDocument))
+ , m_apDialogModel(new DialogModel(xChartDocument))
+ , m_bRangeChooserTabIsValid(true)
+ , m_bDataSourceTabIsValid(true)
+ , m_bTogglingEnabled(true)
+ , m_xTabControl(m_xBuilder->weld_notebook("tabcontrol"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+{
+ m_xRangeChooserTabPage = std::make_unique<RangeChooserTabPage>(m_xTabControl->get_page("range"), this,
+ *m_apDialogModel,
+ m_apDocTemplateProvider.get(), true /* bHideDescription */ );
+ m_xDataSourceTabPage = std::make_unique<DataSourceTabPage>(m_xTabControl->get_page("series"), this,
+ *m_apDialogModel,
+ m_apDocTemplateProvider.get(), true /* bHideDescription */ );
+ m_xTabControl->connect_enter_page(LINK(this, DataSourceDialog, ActivatePageHdl));
+ m_xTabControl->connect_leave_page(LINK(this, DataSourceDialog, DeactivatePageHdl));
+ ActivatePageHdl(m_xTabControl->get_current_page_ident());
+ if (m_nLastPageId != 0)
+ {
+ m_xTabControl->set_current_page(m_nLastPageId);
+ ActivatePageHdl(m_xTabControl->get_current_page_ident());
+ }
+}
+
+DataSourceDialog::~DataSourceDialog()
+{
+ m_xRangeChooserTabPage.reset();
+ m_xDataSourceTabPage.reset();
+ m_nLastPageId = m_xTabControl->get_current_page();
+}
+
+short DataSourceDialog::run()
+{
+ short nResult = GenericDialogController::run();
+ if( nResult == RET_OK )
+ {
+ if( m_xRangeChooserTabPage )
+ m_xRangeChooserTabPage->commitPage();
+ if( m_xDataSourceTabPage )
+ m_xDataSourceTabPage->commitPage();
+ }
+ return nResult;
+}
+
+IMPL_LINK(DataSourceDialog, ActivatePageHdl, const OUString&, rPage, void)
+{
+ if (rPage == "range")
+ m_xRangeChooserTabPage->Activate();
+ else if (rPage == "series")
+ m_xDataSourceTabPage->Activate();
+}
+
+// allow/disallow user to leave page
+IMPL_LINK_NOARG(DataSourceDialog, DeactivatePageHdl, const OUString&, bool)
+{
+ return m_bTogglingEnabled;
+}
+
+void DataSourceDialog::setInvalidPage(BuilderPage* pTabPage)
+{
+ if (pTabPage == m_xRangeChooserTabPage.get())
+ m_bRangeChooserTabIsValid = false;
+ else if (pTabPage == m_xDataSourceTabPage.get())
+ m_bDataSourceTabIsValid = false;
+
+ if (!(m_bRangeChooserTabIsValid && m_bDataSourceTabIsValid))
+ {
+ m_xBtnOK->set_sensitive(false);
+ // note: there seems to be no suitable mechanism to address pages by
+ // identifier, at least it is unclear what the page identifiers are.
+ // @todo: change the fixed numbers to identifiers
+ if( m_bRangeChooserTabIsValid )
+ m_xTabControl->set_current_page(1);
+ else if( m_bDataSourceTabIsValid )
+ m_xTabControl->set_current_page(0);
+ m_bTogglingEnabled = false;
+ }
+}
+
+void DataSourceDialog::setValidPage(BuilderPage* pTabPage)
+{
+ if( pTabPage == m_xRangeChooserTabPage.get() )
+ m_bRangeChooserTabIsValid = true;
+ else if( pTabPage == m_xDataSourceTabPage.get() )
+ m_bDataSourceTabIsValid = true;
+
+ if (m_bRangeChooserTabIsValid && m_bDataSourceTabIsValid)
+ {
+ m_xBtnOK->set_sensitive(true);
+ m_bTogglingEnabled = true;
+ }
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertAxis_Grid.cxx b/chart2/source/controller/dialogs/dlg_InsertAxis_Grid.cxx
new file mode 100644
index 0000000000..6a79bac4a4
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertAxis_Grid.cxx
@@ -0,0 +1,88 @@
+/* -*- 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 .
+ */
+
+#include <dlg_InsertAxis_Grid.hxx>
+
+namespace chart
+{
+
+InsertAxisOrGridDialogData::InsertAxisOrGridDialogData()
+ : aPossibilityList{ true, true, true, true, true, true }
+ , aExistenceList{ false, false, false, false, false, false }
+{
+}
+
+// SchAxisDlg
+
+SchAxisDlg::SchAxisDlg(weld::Window* pWindow,
+ const InsertAxisOrGridDialogData& rInput, bool bAxisDlg)
+ : GenericDialogController(pWindow,
+ bAxisDlg ?
+ OUString("modules/schart/ui/insertaxisdlg.ui") :
+ OUString("modules/schart/ui/insertgriddlg.ui"),
+ bAxisDlg ?
+ OUString("InsertAxisDialog") :
+ OUString("InsertGridDialog"))
+ , m_xCbPrimaryX(m_xBuilder->weld_check_button("primaryX"))
+ , m_xCbPrimaryY(m_xBuilder->weld_check_button("primaryY"))
+ , m_xCbPrimaryZ(m_xBuilder->weld_check_button("primaryZ"))
+ , m_xCbSecondaryX(m_xBuilder->weld_check_button("secondaryX"))
+ , m_xCbSecondaryY(m_xBuilder->weld_check_button("secondaryY"))
+ , m_xCbSecondaryZ(m_xBuilder->weld_check_button("secondaryZ"))
+{
+ if (bAxisDlg)
+ {
+ //todo: remove if secondary z axis are possible somewhere
+ m_xCbSecondaryZ->hide();
+ }
+
+ m_xCbPrimaryX->set_active( rInput.aExistenceList[0] );
+ m_xCbPrimaryY->set_active( rInput.aExistenceList[1] );
+ m_xCbPrimaryZ->set_active( rInput.aExistenceList[2] );
+ m_xCbSecondaryX->set_active( rInput.aExistenceList[3] );
+ m_xCbSecondaryY->set_active( rInput.aExistenceList[4] );
+ m_xCbSecondaryZ->set_active( rInput.aExistenceList[5] );
+
+ m_xCbPrimaryX->set_sensitive( rInput.aPossibilityList[0] );
+ m_xCbPrimaryY->set_sensitive( rInput.aPossibilityList[1] );
+ m_xCbPrimaryZ->set_sensitive( rInput.aPossibilityList[2] );
+ m_xCbSecondaryX->set_sensitive( rInput.aPossibilityList[3] );
+ m_xCbSecondaryY->set_sensitive( rInput.aPossibilityList[4] );
+ m_xCbSecondaryZ->set_sensitive( rInput.aPossibilityList[5] );
+}
+
+void SchAxisDlg::getResult( InsertAxisOrGridDialogData& rOutput )
+{
+ sal_Bool* pExistenceList = rOutput.aExistenceList.getArray();
+ pExistenceList[0]=m_xCbPrimaryX->get_active();
+ pExistenceList[1]=m_xCbPrimaryY->get_active();
+ pExistenceList[2]=m_xCbPrimaryZ->get_active();
+ pExistenceList[3]=m_xCbSecondaryX->get_active();
+ pExistenceList[4]=m_xCbSecondaryY->get_active();
+ pExistenceList[5]=m_xCbSecondaryZ->get_active();
+}
+
+SchGridDlg::SchGridDlg(weld::Window* pParent, const InsertAxisOrGridDialogData& rInput)
+ : SchAxisDlg(pParent, rInput, false) //rInAttrs, b3D, bNet, bSecondaryX, bSecondaryY, false )
+{
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertDataLabel.cxx b/chart2/source/controller/dialogs/dlg_InsertDataLabel.cxx
new file mode 100644
index 0000000000..57817d883d
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertDataLabel.cxx
@@ -0,0 +1,43 @@
+/* -*- 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 .
+ */
+
+#include <dlg_InsertDataLabel.hxx>
+#include "res_DataLabel.hxx"
+
+namespace chart
+{
+
+DataLabelsDialog::DataLabelsDialog(weld::Window* pWindow, const SfxItemSet& rInAttrs, SvNumberFormatter* pFormatter)
+ : GenericDialogController(pWindow, "modules/schart/ui/dlg_DataLabel.ui", "dlg_DataLabels")
+ , m_apDataLabelResources(new DataLabelResources(m_xBuilder.get(), pWindow, rInAttrs))
+{
+ m_apDataLabelResources->SetNumberFormatter( pFormatter );
+ m_apDataLabelResources->Reset(rInAttrs);
+}
+
+DataLabelsDialog::~DataLabelsDialog() = default;
+
+void DataLabelsDialog::FillItemSet(SfxItemSet& rOutAttrs)
+{
+ m_apDataLabelResources->FillItemSet(&rOutAttrs);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertDataTable.cxx b/chart2/source/controller/dialogs/dlg_InsertDataTable.cxx
new file mode 100644
index 0000000000..4b5e928db0
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertDataTable.cxx
@@ -0,0 +1,61 @@
+/* -*- 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/.
+ */
+
+#include <dlg_InsertDataTable.hxx>
+
+namespace chart
+{
+InsertDataTableDialog::InsertDataTableDialog(weld::Window* pWindow)
+ : GenericDialogController(pWindow, "modules/schart/ui/dlg_InsertDataTable.ui",
+ "InsertDataTableDialog")
+ , m_aDataTablePropertiesResources(*m_xBuilder)
+ , m_xCbShowDataTable(m_xBuilder->weld_check_button("showDataTable"))
+{
+ m_xCbShowDataTable->connect_toggled(LINK(this, InsertDataTableDialog, ShowDataTableToggle));
+ init(m_aData);
+}
+
+IMPL_LINK_NOARG(InsertDataTableDialog, ShowDataTableToggle, weld::Toggleable&, void)
+{
+ changeEnabled();
+}
+
+void InsertDataTableDialog::changeEnabled()
+{
+ bool bEnable = m_xCbShowDataTable->get_active();
+ m_aDataTablePropertiesResources.setChecksSensitive(bEnable);
+ m_aData.mbShow = bEnable;
+}
+
+void InsertDataTableDialog::init(DataTableDialogData const& rData)
+{
+ m_aData = rData;
+ m_aDataTablePropertiesResources.setHorizontalBorder(m_aData.mbHorizontalBorders);
+ m_aDataTablePropertiesResources.setVerticalBorder(m_aData.mbVerticalBorders);
+ m_aDataTablePropertiesResources.setOutline(m_aData.mbOutline);
+ m_aDataTablePropertiesResources.setKeys(m_aData.mbKeys);
+ m_xCbShowDataTable->set_active(m_aData.mbShow);
+ changeEnabled();
+}
+
+DataTableDialogData& InsertDataTableDialog::getDataTableDialogData()
+{
+ m_aData.mbShow = m_xCbShowDataTable->get_active();
+
+ m_aData.mbHorizontalBorders = m_aDataTablePropertiesResources.getHorizontalBorder();
+ m_aData.mbVerticalBorders = m_aDataTablePropertiesResources.getVerticalBorder();
+ m_aData.mbOutline = m_aDataTablePropertiesResources.getOutline();
+ m_aData.mbKeys = m_aDataTablePropertiesResources.getKeys();
+
+ return m_aData;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertErrorBars.cxx b/chart2/source/controller/dialogs/dlg_InsertErrorBars.cxx
new file mode 100644
index 0000000000..807e902856
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertErrorBars.cxx
@@ -0,0 +1,103 @@
+/* -*- 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 .
+ */
+
+#include <dlg_InsertErrorBars.hxx>
+#include <res_ErrorBar.hxx>
+#include <chartview/ExplicitScaleValues.hxx>
+#include <chartview/ExplicitValueProvider.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <ChartView.hxx>
+#include <ObjectIdentifier.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <Axis.hxx>
+#include <AxisHelper.hxx>
+#include <ObjectNameProvider.hxx>
+#include <DataSeries.hxx>
+
+#include <comphelper/servicehelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+namespace chart
+{
+
+InsertErrorBarsDialog::InsertErrorBarsDialog(
+ weld::Window* pParent, const SfxItemSet& rMyAttrs,
+ const rtl::Reference<::chart::ChartModel> & xChartDocument,
+ ErrorBarResources::tErrorBarType eType /* = ErrorBarResources::ERROR_BAR_Y */ )
+ : GenericDialogController(pParent, "modules/schart/ui/dlg_InsertErrorBars.ui", "dlg_InsertErrorBars")
+ , m_apErrorBarResources( new ErrorBarResources(
+ m_xBuilder.get(), this, rMyAttrs,
+ /* bNoneAvailable = */ true, eType ))
+{
+ ObjectType objType = eType == ErrorBarResources::ERROR_BAR_Y ? OBJECTTYPE_DATA_ERRORS_Y : OBJECTTYPE_DATA_ERRORS_X;
+
+ m_xDialog->set_title(ObjectNameProvider::getName_ObjectForAllSeries(objType));
+
+ m_apErrorBarResources->SetChartDocumentForRangeChoosing( xChartDocument );
+}
+
+void InsertErrorBarsDialog::FillItemSet(SfxItemSet& rOutAttrs)
+{
+ m_apErrorBarResources->FillItemSet(rOutAttrs);
+}
+
+void InsertErrorBarsDialog::SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth )
+{
+ m_apErrorBarResources->SetAxisMinorStepWidthForErrorBarDecimals( fMinorStepWidth );
+}
+
+double InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals(
+ const rtl::Reference<::chart::ChartModel>& xChartModel,
+ const rtl::Reference<::chart::ChartView>& xChartView,
+ std::u16string_view rSelectedObjectCID )
+{
+ double fStepWidth = 0.001;
+
+ ExplicitValueProvider* pExplicitValueProvider( xChartView.get() );
+ if( pExplicitValueProvider )
+ {
+ rtl::Reference< Diagram > xDiagram( xChartModel->getFirstChartDiagram() );
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( rSelectedObjectCID, xChartModel );
+ rtl::Reference< Axis > xAxis = xDiagram->getAttachedAxis( xSeries );
+ if(!xAxis.is())
+ xAxis = AxisHelper::getAxis( 1/*nDimensionIndex*/, true/*bMainAxis*/, xDiagram );
+ if(xAxis.is())
+ {
+ ExplicitScaleData aExplicitScale;
+ ExplicitIncrementData aExplicitIncrement;
+ pExplicitValueProvider->getExplicitValuesForAxis( xAxis,aExplicitScale, aExplicitIncrement );
+
+ fStepWidth = aExplicitIncrement.Distance;
+ if( !aExplicitIncrement.SubIncrements.empty() && aExplicitIncrement.SubIncrements[0].IntervalCount>0 )
+ fStepWidth=fStepWidth/double(aExplicitIncrement.SubIncrements[0].IntervalCount);
+ else
+ fStepWidth/=10;
+ }
+ }
+
+ return fStepWidth;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertLegend.cxx b/chart2/source/controller/dialogs/dlg_InsertLegend.cxx
new file mode 100644
index 0000000000..c55ecc3e88
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertLegend.cxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#include <dlg_InsertLegend.hxx>
+#include <res_LegendPosition.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+
+SchLegendDlg::SchLegendDlg(weld::Window* pWindow, const uno::Reference<uno::XComponentContext>& xCC)
+ : GenericDialogController(pWindow, "modules/schart/ui/dlg_InsertLegend.ui", "dlg_InsertLegend")
+ , m_xLegendPositionResources(new LegendPositionResources(*m_xBuilder, xCC))
+{
+}
+
+void SchLegendDlg::init(const rtl::Reference<::chart::ChartModel>& xChartModel)
+{
+ m_xLegendPositionResources->writeToResources(xChartModel);
+}
+
+void SchLegendDlg::writeToModel(const rtl::Reference<::chart::ChartModel>& xChartModel) const
+{
+ m_xLegendPositionResources->writeToModel(xChartModel);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_InsertTitle.cxx b/chart2/source/controller/dialogs/dlg_InsertTitle.cxx
new file mode 100644
index 0000000000..03f9429458
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_InsertTitle.cxx
@@ -0,0 +1,41 @@
+/* -*- 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 .
+ */
+
+#include <dlg_InsertTitle.hxx>
+#include <res_Titles.hxx>
+#include <ObjectNameProvider.hxx>
+
+namespace chart
+{
+SchTitleDlg::SchTitleDlg(weld::Window* pWindow, const TitleDialogData& rInput)
+ : GenericDialogController(pWindow, "modules/schart/ui/inserttitledlg.ui", "InsertTitleDialog")
+ , m_xTitleResources(new TitleResources(*m_xBuilder, true))
+{
+ m_xDialog->set_title(ObjectNameProvider::getName(OBJECTTYPE_TITLE, true));
+ m_xTitleResources->writeToResources(rInput);
+}
+
+void SchTitleDlg::getResult(TitleDialogData& rOutput)
+{
+ m_xTitleResources->readFromResources(rOutput);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_NumberFormat.cxx b/chart2/source/controller/dialogs/dlg_NumberFormat.cxx
new file mode 100644
index 0000000000..f5cfe8e3bd
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_NumberFormat.cxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+
+#include "dlg_NumberFormat.hxx"
+
+#include <svl/itemset.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <sfx2/tabdlg.hxx>
+#include <sfx2/sfxdlg.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+
+NumberFormatDialog::NumberFormatDialog(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet, "cui/ui/formatnumberdialog.ui", "FormatNumberDialog")
+ , m_xContent( m_xBuilder->weld_container("content") )
+{
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
+ if (fnCreatePage)
+ {
+ std::unique_ptr<SfxTabPage> xTabPage = (*fnCreatePage)(m_xContent.get(), this, &rSet);
+ xTabPage->PageCreated(rSet);
+ SetTabPage(std::move(xTabPage));
+ }
+}
+
+SfxItemSet NumberFormatDialog::CreateEmptyItemSetForNumberFormatDialog( SfxItemPool& rItemPool )
+{
+ return SfxItemSet( rItemPool, svl::Items<
+ SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_INFO,
+ SID_ATTR_NUMBERFORMAT_ONE_AREA, SID_ATTR_NUMBERFORMAT_ONE_AREA,
+ SID_ATTR_NUMBERFORMAT_NOLANGUAGE, SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
+ SID_ATTR_NUMBERFORMAT_SOURCE, SID_ATTR_NUMBERFORMAT_SOURCE> );
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_NumberFormat.hxx b/chart2/source/controller/dialogs/dlg_NumberFormat.hxx
new file mode 100644
index 0000000000..be02edeb62
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_NumberFormat.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/basedlgs.hxx>
+
+namespace weld
+{
+class Window;
+class Container;
+}
+class SfxItemSet;
+class SfxItemPool;
+
+namespace chart
+{
+class NumberFormatDialog : public SfxSingleTabDialogController
+{
+ std::unique_ptr<weld::Container> m_xContent;
+
+public:
+ NumberFormatDialog(weld::Window* pParent, const SfxItemSet& rSet);
+
+ static SfxItemSet CreateEmptyItemSetForNumberFormatDialog(SfxItemPool& rItemPool);
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx b/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
new file mode 100644
index 0000000000..e885fdaef3
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
@@ -0,0 +1,638 @@
+/* -*- 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 .
+ */
+
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include <dlg_ObjectProperties.hxx>
+#include <strings.hrc>
+#include "tp_AxisLabel.hxx"
+#include "tp_DataLabel.hxx"
+#include "tp_LegendPosition.hxx"
+#include "tp_PointGeometry.hxx"
+#include "tp_Scale.hxx"
+#include "tp_AxisPositions.hxx"
+#include "tp_ErrorBars.hxx"
+#include "tp_Trendline.hxx"
+#include "tp_SeriesToAxis.hxx"
+#include "tp_TitleRotation.hxx"
+#include "tp_PolarOptions.hxx"
+#include "tp_DataPointOption.hxx"
+#include "tp_DataTable.hxx"
+#include <ResId.hxx>
+#include <ViewElementListProvider.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeHelper.hxx>
+#include <ObjectNameProvider.hxx>
+#include <DataSeries.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <NumberFormatterWrapper.hxx>
+#include <Axis.hxx>
+#include <AxisHelper.hxx>
+#include <ExplicitCategoriesProvider.hxx>
+#include <ChartModel.hxx>
+#include <CommonConverters.hxx>
+#include <RegressionCalculationHelper.hxx>
+#include <BaseCoordinateSystem.hxx>
+
+#include <com/sun/star/chart2/AxisType.hpp>
+#include <com/sun/star/chart2/XAxis.hpp>
+#include <svl/intitem.hxx>
+#include <svl/ctloptions.hxx>
+
+#include <svx/svxids.hrc>
+
+#include <svx/drawitem.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/svxgraphicitem.hxx>
+
+#include <svx/dialogs.hrc>
+#include <editeng/flstitem.hxx>
+
+#include <svx/flagsdef.hxx>
+#include <svx/numinf.hxx>
+
+#include <svl/cjkoptions.hxx>
+#include <utility>
+#include <comphelper/diagnose_ex.hxx>
+
+namespace com::sun::star::chart2 { class XChartType; }
+namespace com::sun::star::chart2 { class XDataSeries; }
+
+namespace chart
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::beans::XPropertySet;
+
+ObjectPropertiesDialogParameter::ObjectPropertiesDialogParameter( OUString aObjectCID )
+ : m_aObjectCID(std::move( aObjectCID ))
+ , m_eObjectType( ObjectIdentifier::getObjectType( m_aObjectCID ) )
+ , m_bAffectsMultipleObjects(false)
+ , m_bHasGeometryProperties(false)
+ , m_bHasStatisticProperties(false)
+ , m_bProvidesSecondaryYAxis(false)
+ , m_bProvidesOverlapAndGapWidth(false)
+ , m_bProvidesBarConnectors(false)
+ , m_bHasAreaProperties(false)
+ , m_bHasSymbolProperties(false)
+ , m_bHasNumberProperties(false)
+ , m_bProvidesStartingAngle(false)
+ , m_bProvidesMissingValueTreatments(false)
+ , m_bIsPieChartDataPoint(false)
+ , m_bHasScaleProperties(false)
+ , m_bCanAxisLabelsBeStaggered(false)
+ , m_bSupportingAxisPositioning(false)
+ , m_bShowAxisOrigin(false)
+ , m_bIsCrossingAxisIsCategoryAxis(false)
+ , m_bSupportingCategoryPositioning(false)
+ , m_bComplexCategoriesAxis( false )
+ , m_nNbPoints( 0 )
+{
+ std::u16string_view aParticleID = ObjectIdentifier::getParticleID( m_aObjectCID );
+ m_bAffectsMultipleObjects = (aParticleID == u"ALLELEMENTS");
+}
+ObjectPropertiesDialogParameter::~ObjectPropertiesDialogParameter()
+{
+}
+
+void ObjectPropertiesDialogParameter::init( const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ m_xChartDocument = xChartModel;
+ rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
+ rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aObjectCID, xChartModel );
+ rtl::Reference< ChartType > xChartType = ChartModelHelper::getChartTypeOfSeries( xChartModel, xSeries );
+ sal_Int32 nDimensionCount = 0;
+ if (xDiagram)
+ nDimensionCount = xDiagram->getDimension();
+
+ bool bHasSeriesProperties = (m_eObjectType==OBJECTTYPE_DATA_SERIES);
+ bool bHasDataPointproperties = (m_eObjectType==OBJECTTYPE_DATA_POINT);
+
+ if( bHasSeriesProperties || bHasDataPointproperties )
+ {
+ m_bHasGeometryProperties = ChartTypeHelper::isSupportingGeometryProperties( xChartType, nDimensionCount );
+ m_bHasAreaProperties = ChartTypeHelper::isSupportingAreaProperties( xChartType, nDimensionCount );
+ m_bHasSymbolProperties = ChartTypeHelper::isSupportingSymbolProperties( xChartType, nDimensionCount );
+ m_bIsPieChartDataPoint = bHasDataPointproperties && ChartTypeHelper::isSupportingStartingAngle( xChartType );
+
+ if( bHasSeriesProperties )
+ {
+ m_bHasStatisticProperties = ChartTypeHelper::isSupportingStatisticProperties( xChartType, nDimensionCount );
+ m_bProvidesSecondaryYAxis = ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimensionCount );
+ m_bProvidesOverlapAndGapWidth = ChartTypeHelper::isSupportingOverlapAndGapWidthProperties( xChartType, nDimensionCount );
+ m_bProvidesBarConnectors = ChartTypeHelper::isSupportingBarConnectors( xChartType, nDimensionCount );
+ m_bProvidesStartingAngle = ChartTypeHelper::isSupportingStartingAngle( xChartType );
+
+ m_bProvidesMissingValueTreatments = ChartTypeHelper::getSupportedMissingValueTreatments( xChartType )
+ .hasElements();
+ }
+ }
+
+ if( m_eObjectType == OBJECTTYPE_DATA_ERRORS_X ||
+ m_eObjectType == OBJECTTYPE_DATA_ERRORS_Y ||
+ m_eObjectType == OBJECTTYPE_DATA_ERRORS_Z)
+ m_bHasStatisticProperties = true;
+
+ if( m_eObjectType == OBJECTTYPE_AXIS )
+ {
+ //show scale properties only for a single axis not for multiselection
+ m_bHasScaleProperties = !m_bAffectsMultipleObjects;
+
+ if( m_bHasScaleProperties )
+ {
+ rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( m_aObjectCID, xChartModel );
+ if( xAxis.is() )
+ {
+ //no scale page for series axis
+ ScaleData aData( xAxis->getScaleData() );
+ if( aData.AxisType == chart2::AxisType::SERIES )
+ m_bHasScaleProperties = false;
+ if( aData.AxisType != chart2::AxisType::SERIES )
+ m_bHasNumberProperties = true;
+
+ //is the crossing main axis a category axes?:
+ rtl::Reference< BaseCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, xDiagram ) );
+ uno::Reference< XAxis > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis, xCooSys ) );
+ if( xCrossingMainAxis.is() )
+ {
+ ScaleData aScale( xCrossingMainAxis->getScaleData() );
+ m_bIsCrossingAxisIsCategoryAxis = ( aScale.AxisType == chart2::AxisType::CATEGORY );
+ if( m_bIsCrossingAxisIsCategoryAxis )
+ {
+ if (xChartModel)
+ m_aCategories = DiagramHelper::getExplicitSimpleCategories( *xChartModel );
+ }
+ }
+
+ sal_Int32 nCooSysIndex=0;
+ sal_Int32 nDimensionIndex=0;
+ sal_Int32 nAxisIndex=0;
+ if( AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ) )
+ {
+ xChartType = AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( xDiagram, nAxisIndex );
+ //show positioning controls only if they make sense
+ m_bSupportingAxisPositioning = ChartTypeHelper::isSupportingAxisPositioning( xChartType, nDimensionCount, nDimensionIndex );
+
+ //show axis origin only for secondary y axis
+ if( nDimensionIndex==1 && nAxisIndex==1 && ChartTypeHelper::isSupportingBaseValue( xChartType ) )
+ m_bShowAxisOrigin = true;
+
+ if ( nDimensionIndex == 0 && ( aData.AxisType == chart2::AxisType::CATEGORY || aData.AxisType == chart2::AxisType::DATE ) )
+ {
+ if (xChartModel)
+ {
+ ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, *xChartModel );
+ m_bComplexCategoriesAxis = aExplicitCategoriesProvider.hasComplexCategories();
+ }
+
+ if (!m_bComplexCategoriesAxis)
+ m_bSupportingCategoryPositioning = ChartTypeHelper::isSupportingCategoryPositioning( xChartType, nDimensionCount );
+ }
+ }
+ }
+ }
+
+ //no staggering of labels for 3D axis
+ m_bCanAxisLabelsBeStaggered = nDimensionCount==2;
+ }
+
+ if( m_eObjectType == OBJECTTYPE_DATA_CURVE )
+ {
+ const std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > & aDataSeqs( xSeries->getDataSequences2());
+ Sequence< double > aXValues, aYValues;
+ bool bXValuesFound = false, bYValuesFound = false;
+ m_nNbPoints = 0;
+ for( std::size_t i=0;
+ ! (bXValuesFound && bYValuesFound) && i<aDataSeqs.size();
+ ++i )
+ {
+ try
+ {
+ Reference< data::XDataSequence > xSeq( aDataSeqs[i]->getValues());
+ Reference< XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
+ OUString aRole;
+ if( xProp->getPropertyValue( "Role" ) >>= aRole )
+ {
+ if( !bXValuesFound && aRole == "values-x" )
+ {
+ aXValues = DataSequenceToDoubleSequence( xSeq );
+ bXValuesFound = true;
+ }
+ else if( !bYValuesFound && aRole == "values-y" )
+ {
+ aYValues = DataSequenceToDoubleSequence( xSeq );
+ bYValuesFound = true;
+ }
+ }
+ }
+ catch( const Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ if( !bXValuesFound && bYValuesFound )
+ {
+ // initialize with 1, 2, ...
+ //first category (index 0) matches with real number 1.0
+ aXValues.realloc( aYValues.getLength() );
+ auto pXValues = aXValues.getArray();
+ for( sal_Int32 i=0; i<aXValues.getLength(); ++i )
+ pXValues[i] = i+1;
+ bXValuesFound = true;
+ }
+
+ if( bXValuesFound && bYValuesFound &&
+ aXValues.hasElements() &&
+ aYValues.hasElements() )
+ {
+ RegressionCalculationHelper::tDoubleVectorPair aValues(
+ RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValid()));
+ m_nNbPoints = aValues.second.size();
+ }
+ }
+
+ //create gui name for this object
+ {
+ if( !m_bAffectsMultipleObjects && m_eObjectType == OBJECTTYPE_AXIS )
+ {
+ m_aLocalizedName = ObjectNameProvider::getAxisName( m_aObjectCID, xChartModel );
+ }
+ else if( !m_bAffectsMultipleObjects && ( m_eObjectType == OBJECTTYPE_GRID || m_eObjectType == OBJECTTYPE_SUBGRID ) )
+ {
+ m_aLocalizedName = ObjectNameProvider::getGridName( m_aObjectCID, xChartModel );
+ }
+ else if( !m_bAffectsMultipleObjects && m_eObjectType == OBJECTTYPE_TITLE )
+ {
+ m_aLocalizedName = ObjectNameProvider::getTitleName( m_aObjectCID, xChartModel );
+ }
+ else
+ {
+ switch( m_eObjectType )
+ {
+ case OBJECTTYPE_DATA_POINT:
+ case OBJECTTYPE_DATA_LABEL:
+ case OBJECTTYPE_DATA_LABELS:
+ case OBJECTTYPE_DATA_ERRORS_X:
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ case OBJECTTYPE_DATA_CURVE:
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ if( m_bAffectsMultipleObjects )
+ m_aLocalizedName = ObjectNameProvider::getName_ObjectForAllSeries( m_eObjectType );
+ else
+ m_aLocalizedName = ObjectNameProvider::getName_ObjectForSeries( m_eObjectType, m_aObjectCID, m_xChartDocument );
+ break;
+ default:
+ m_aLocalizedName = ObjectNameProvider::getName(m_eObjectType,m_bAffectsMultipleObjects);
+ break;
+ }
+ }
+ }
+}
+
+const sal_uInt16 nNoArrowNoShadowDlg = 1101;
+
+void SchAttribTabDlg::setSymbolInformation( SfxItemSet&& rSymbolShapeProperties,
+ std::optional<Graphic> oAutoSymbolGraphic )
+{
+ m_oSymbolShapeProperties.emplace(std::move(rSymbolShapeProperties));
+ m_oAutoSymbolGraphic = std::move(oAutoSymbolGraphic);
+}
+
+void SchAttribTabDlg::SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth )
+{
+ m_fAxisMinorStepWidthForErrorBarDecimals = fMinorStepWidth;
+}
+
+SchAttribTabDlg::SchAttribTabDlg(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const ObjectPropertiesDialogParameter* pDialogParameter,
+ const ViewElementListProvider* pViewElementListProvider,
+ const uno::Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier)
+ : SfxTabDialogController(pParent, "modules/schart/ui/attributedialog.ui", "AttributeDialog", pAttr)
+ , m_pParameter( pDialogParameter )
+ , m_pViewElementListProvider( pViewElementListProvider )
+ , m_pNumberFormatter(nullptr)
+ , m_fAxisMinorStepWidthForErrorBarDecimals(0.1)
+ , m_bOKPressed(false)
+{
+ NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier );
+ m_pNumberFormatter = aNumberFormatterWrapper.getSvNumberFormatter();
+
+ m_xDialog->set_title(pDialogParameter->getLocalizedName());
+
+ switch (pDialogParameter->getObjectType())
+ {
+ case OBJECTTYPE_TITLE:
+ AddTabPage("border", SchResId(STR_PAGE_BORDER), RID_SVXPAGE_LINE);
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("transparent", SchResId(STR_PAGE_TRANSPARENCY), RID_SVXPAGE_TRANSPARENCE);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("alignment", SchResId(STR_PAGE_ALIGNMENT), SchAlignmentTabPage::Create);
+ if( SvtCJKOptions::IsAsianTypographyEnabled() )
+ AddTabPage("asian", SchResId(STR_PAGE_ASIAN), RID_SVXPAGE_PARA_ASIAN);
+ break;
+
+ case OBJECTTYPE_LEGEND:
+ AddTabPage("border", SchResId(STR_PAGE_BORDER), RID_SVXPAGE_LINE);
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("transparent", SchResId(STR_PAGE_TRANSPARENCY), RID_SVXPAGE_TRANSPARENCE);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("legendpos", SchResId(STR_PAGE_POSITION), SchLegendPosTabPage::Create);
+ if (SvtCJKOptions::IsAsianTypographyEnabled())
+ AddTabPage("asian", SchResId(STR_PAGE_ASIAN), RID_SVXPAGE_PARA_ASIAN);
+ break;
+
+ case OBJECTTYPE_DATA_SERIES:
+ case OBJECTTYPE_DATA_POINT:
+ if( m_pParameter->ProvidesSecondaryYAxis() || m_pParameter->ProvidesOverlapAndGapWidth() || m_pParameter->ProvidesMissingValueTreatments() )
+ AddTabPage("options", SchResId(STR_PAGE_OPTIONS),SchOptionTabPage::Create);
+ if( m_pParameter->ProvidesStartingAngle())
+ AddTabPage("polaroptions", SchResId(STR_PAGE_OPTIONS), PolarOptionsTabPage::Create);
+ if (m_pParameter->IsPieChartDataPoint())
+ AddTabPage("datapointoption", SchResId(STR_PAGE_OPTIONS), DataPointOptionTabPage::Create);
+
+ if( m_pParameter->HasGeometryProperties() )
+ AddTabPage("layout", SchResId(STR_PAGE_LAYOUT), SchLayoutTabPage::Create);
+
+ if(m_pParameter->HasAreaProperties())
+ {
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("transparent", SchResId(STR_PAGE_TRANSPARENCY), RID_SVXPAGE_TRANSPARENCE);
+ }
+ AddTabPage("border", SchResId( m_pParameter->HasAreaProperties() ? STR_PAGE_BORDER : STR_PAGE_LINE ), RID_SVXPAGE_LINE);
+ break;
+
+ case OBJECTTYPE_DATA_LABEL:
+ case OBJECTTYPE_DATA_LABELS:
+ AddTabPage("border", SchResId(STR_PAGE_BORDER), RID_SVXPAGE_LINE);
+ AddTabPage("datalabels", SchResId(STR_OBJECT_DATALABELS), DataLabelsTabPage::Create);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ if( SvtCJKOptions::IsAsianTypographyEnabled() )
+ AddTabPage("asian", SchResId(STR_PAGE_ASIAN), RID_SVXPAGE_PARA_ASIAN);
+
+ break;
+
+ case OBJECTTYPE_AXIS:
+ {
+ if( m_pParameter->HasScaleProperties() )
+ {
+ AddTabPage("scale", SchResId(STR_PAGE_SCALE), ScaleTabPage::Create);
+ //no positioning page for z axes so far as the tickmarks are not shown so far
+ AddTabPage("axispos", SchResId(STR_PAGE_POSITIONING), AxisPositionsTabPage::Create);
+ }
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ AddTabPage("axislabel", SchResId(STR_OBJECT_LABEL), SchAxisLabelTabPage::Create);
+ if( m_pParameter->HasNumberProperties() )
+ AddTabPage("numberformat", SchResId(STR_PAGE_NUMBERS), RID_SVXPAGE_NUMBERFORMAT);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ if( SvtCJKOptions::IsAsianTypographyEnabled() )
+ AddTabPage("asian", SchResId(STR_PAGE_ASIAN), RID_SVXPAGE_PARA_ASIAN);
+ break;
+ }
+
+ case OBJECTTYPE_DATA_ERRORS_X:
+ AddTabPage("xerrorbar", SchResId(STR_PAGE_XERROR_BARS), ErrorBarsTabPage::Create);
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ break;
+
+ case OBJECTTYPE_DATA_ERRORS_Y:
+ AddTabPage("yerrorbar", SchResId(STR_PAGE_YERROR_BARS), ErrorBarsTabPage::Create);
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ break;
+
+ case OBJECTTYPE_DATA_ERRORS_Z:
+ break;
+
+ case OBJECTTYPE_GRID:
+ case OBJECTTYPE_SUBGRID:
+ case OBJECTTYPE_DATA_AVERAGE_LINE:
+ case OBJECTTYPE_DATA_STOCK_RANGE:
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ break;
+
+ case OBJECTTYPE_DATA_CURVE:
+ AddTabPage("trendline", SchResId(STR_PAGE_TRENDLINE_TYPE), TrendlineTabPage::Create);
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ break;
+
+ case OBJECTTYPE_DATA_STOCK_LOSS:
+ case OBJECTTYPE_DATA_STOCK_GAIN:
+ case OBJECTTYPE_PAGE:
+ case OBJECTTYPE_DIAGRAM_FLOOR:
+ case OBJECTTYPE_DIAGRAM_WALL:
+ case OBJECTTYPE_DIAGRAM:
+ AddTabPage("border", SchResId(STR_PAGE_BORDER), RID_SVXPAGE_LINE);
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("transparent", SchResId(STR_PAGE_TRANSPARENCY), RID_SVXPAGE_TRANSPARENCE);
+ break;
+
+ case OBJECTTYPE_LEGEND_ENTRY:
+ case OBJECTTYPE_AXIS_UNITLABEL:
+ case OBJECTTYPE_UNKNOWN:
+ // nothing
+ break;
+ case OBJECTTYPE_DATA_TABLE:
+ AddTabPage("datatable", SchResId(STR_DATA_TABLE), DataTableTabPage::Create);
+ AddTabPage("border", SchResId(STR_PAGE_LINE), RID_SVXPAGE_LINE);
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ break;
+ case OBJECTTYPE_DATA_CURVE_EQUATION:
+ AddTabPage("border", SchResId(STR_PAGE_BORDER), RID_SVXPAGE_LINE);
+ AddTabPage("area", SchResId(STR_PAGE_AREA), RID_SVXPAGE_AREA);
+ AddTabPage("transparent", SchResId(STR_PAGE_TRANSPARENCY), RID_SVXPAGE_TRANSPARENCE);
+ AddTabPage("fontname", SchResId(STR_PAGE_FONT), RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", SchResId(STR_PAGE_FONT_EFFECTS), RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("numberformat", SchResId(STR_PAGE_NUMBERS), RID_SVXPAGE_NUMBERFORMAT);
+ if (SvtCTLOptions::IsCTLFontEnabled())
+ {
+ /* When rotation is supported for equation text boxes, use
+ SchAlignmentTabPage::Create here. The special
+ SchAlignmentTabPage::CreateWithoutRotation can be deleted. */
+ AddTabPage("alignment", SchResId(STR_PAGE_ALIGNMENT), SchAlignmentTabPage::CreateWithoutRotation);
+ }
+ break;
+ default:
+ break;
+ }
+
+ // used to find out if user left the dialog with OK. When OK is pressed but
+ // no changes were done, Cancel is returned by the SfxTabDialog. See method
+ // DialogWasClosedWithOK.
+ GetOKButton().connect_clicked(LINK(this, SchAttribTabDlg, OKPressed));
+}
+
+SchAttribTabDlg::~SchAttribTabDlg()
+{
+}
+
+void SchAttribTabDlg::PageCreated(const OUString& rId, SfxTabPage &rPage)
+{
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ if (rId == "border")
+ {
+ aSet.Put (SvxColorListItem(m_pViewElementListProvider->GetColorTable(),SID_COLOR_TABLE));
+ aSet.Put (SvxDashListItem(m_pViewElementListProvider->GetDashList(),SID_DASH_LIST));
+ aSet.Put (SvxLineEndListItem(m_pViewElementListProvider->GetLineEndList(),SID_LINEEND_LIST));
+ aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0));
+ aSet.Put (SfxUInt16Item(SID_DLG_TYPE,nNoArrowNoShadowDlg));
+
+ if( m_pParameter->HasSymbolProperties() )
+ {
+ aSet.Put(OfaPtrItem(SID_OBJECT_LIST,m_pViewElementListProvider->GetSymbolList()));
+ if( m_oSymbolShapeProperties )
+ aSet.Put(SfxTabDialogItem(SID_ATTR_SET, *m_oSymbolShapeProperties));
+ if( m_oAutoSymbolGraphic )
+ aSet.Put(SvxGraphicItem(*m_oAutoSymbolGraphic));
+ }
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "area")
+ {
+ aSet.Put(SvxColorListItem(m_pViewElementListProvider->GetColorTable(),SID_COLOR_TABLE));
+ aSet.Put(SvxGradientListItem(m_pViewElementListProvider->GetGradientList(),SID_GRADIENT_LIST));
+ aSet.Put(SvxHatchListItem(m_pViewElementListProvider->GetHatchList(),SID_HATCH_LIST));
+ aSet.Put(SvxBitmapListItem(m_pViewElementListProvider->GetBitmapList(),SID_BITMAP_LIST));
+ aSet.Put(SvxPatternListItem(m_pViewElementListProvider->GetPatternList(),SID_PATTERN_LIST));
+ aSet.Put(SfxUInt16Item(SID_PAGE_TYPE,0));
+ aSet.Put(SfxUInt16Item(SID_DLG_TYPE,nNoArrowNoShadowDlg));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "transparent")
+ {
+ aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0));
+ aSet.Put (SfxUInt16Item(SID_DLG_TYPE,nNoArrowNoShadowDlg));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "fontname")
+ {
+ aSet.Put (SvxFontListItem(m_pViewElementListProvider->getFontList(), SID_ATTR_CHAR_FONTLIST));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "effects")
+ {
+ aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "axislabel")
+ {
+ bool bShowStaggeringControls = m_pParameter->CanAxisLabelsBeStaggered();
+ auto & rLabelPage = static_cast<SchAxisLabelTabPage&>(rPage);
+ rLabelPage.ShowStaggeringControls( bShowStaggeringControls );
+ rLabelPage.SetComplexCategories( m_pParameter->IsComplexCategoriesAxis() );
+ }
+ else if (rId == "axispos")
+ {
+ AxisPositionsTabPage* pPage = dynamic_cast< AxisPositionsTabPage* >( &rPage );
+ if(pPage)
+ {
+ pPage->SetNumFormatter( m_pNumberFormatter );
+ if( m_pParameter->IsCrossingAxisIsCategoryAxis() )
+ {
+ pPage->SetCrossingAxisIsCategoryAxis( m_pParameter->IsCrossingAxisIsCategoryAxis() );
+ pPage->SetCategories( m_pParameter->GetCategories() );
+ }
+ pPage->SupportAxisPositioning( m_pParameter->IsSupportingAxisPositioning() );
+ pPage->SupportCategoryPositioning( m_pParameter->IsSupportingCategoryPositioning() );
+ }
+ }
+ else if (rId == "scale")
+ {
+ ScaleTabPage* pScaleTabPage = dynamic_cast< ScaleTabPage* >( &rPage );
+ if(pScaleTabPage)
+ {
+ pScaleTabPage->SetNumFormatter( m_pNumberFormatter );
+ pScaleTabPage->ShowAxisOrigin( m_pParameter->ShowAxisOrigin() );
+ }
+ }
+ else if (rId == "datalabels")
+ {
+ DataLabelsTabPage* pLabelPage = dynamic_cast< DataLabelsTabPage* >( &rPage );
+ if( pLabelPage )
+ pLabelPage->SetNumberFormatter( m_pNumberFormatter );
+ }
+ else if (rId == "numberformat")
+ {
+ aSet.Put (SvxNumberInfoItem( m_pNumberFormatter, SID_ATTR_NUMBERFORMAT_INFO));
+ rPage.PageCreated(aSet);
+ }
+ else if (rId == "xerrorbar")
+ {
+ ErrorBarsTabPage * pTabPage = dynamic_cast< ErrorBarsTabPage * >( &rPage );
+ OSL_ASSERT( pTabPage );
+ if( pTabPage )
+ {
+ pTabPage->SetAxisMinorStepWidthForErrorBarDecimals( m_fAxisMinorStepWidthForErrorBarDecimals );
+ pTabPage->SetErrorBarType( ErrorBarResources::ERROR_BAR_X );
+ pTabPage->SetChartDocumentForRangeChoosing( m_pParameter->getDocument());
+ }
+ }
+ else if (rId == "yerrorbar")
+ {
+ ErrorBarsTabPage * pTabPage = dynamic_cast< ErrorBarsTabPage * >( &rPage );
+ OSL_ASSERT( pTabPage );
+ if( pTabPage )
+ {
+ pTabPage->SetAxisMinorStepWidthForErrorBarDecimals( m_fAxisMinorStepWidthForErrorBarDecimals );
+ pTabPage->SetErrorBarType( ErrorBarResources::ERROR_BAR_Y );
+ pTabPage->SetChartDocumentForRangeChoosing( m_pParameter->getDocument());
+ }
+ }
+ else if (rId == "options")
+ {
+ SchOptionTabPage* pTabPage = dynamic_cast< SchOptionTabPage* >( &rPage );
+ if( pTabPage && m_pParameter )
+ pTabPage->Init( m_pParameter->ProvidesSecondaryYAxis(), m_pParameter->ProvidesOverlapAndGapWidth(),
+ m_pParameter->ProvidesBarConnectors() );
+ }
+ else if (rId == "trendline")
+ {
+ TrendlineTabPage* pTrendlineTabPage = dynamic_cast< TrendlineTabPage* >( &rPage );
+ if(pTrendlineTabPage)
+ {
+ pTrendlineTabPage->SetNumFormatter( m_pNumberFormatter );
+ pTrendlineTabPage->SetNbPoints( m_pParameter->getNbPoints() );
+ }
+ }
+}
+
+IMPL_LINK(SchAttribTabDlg, OKPressed, weld::Button&, rButton, void)
+{
+ m_bOKPressed = true;
+ OkHdl(rButton);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_ShapeFont.cxx b/chart2/source/controller/dialogs/dlg_ShapeFont.cxx
new file mode 100644
index 0000000000..b742e8a22e
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_ShapeFont.cxx
@@ -0,0 +1,61 @@
+/* -*- 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 .
+ */
+
+#include <dlg_ShapeFont.hxx>
+#include <ViewElementListProvider.hxx>
+
+#include <svl/intitem.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <svx/flagsdef.hxx>
+#include <editeng/flstitem.hxx>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+ShapeFontDialog::ShapeFontDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const ViewElementListProvider* pViewElementListProvider)
+ : SfxTabDialogController(pParent, "modules/schart/ui/chardialog.ui", "CharDialog", pAttr)
+ , m_pViewElementListProvider(pViewElementListProvider)
+{
+ AddTabPage("font", RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("fonteffects", RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("position", RID_SVXPAGE_CHAR_POSITION );
+}
+
+void ShapeFontDialog::PageCreated(const OUString& rId, SfxTabPage& rPage)
+{
+ SfxAllItemSet aSet( *( GetInputSetImpl()->GetPool() ) );
+ if (rId == "font")
+ {
+ aSet.Put( SvxFontListItem( m_pViewElementListProvider->getFontList(), SID_ATTR_CHAR_FONTLIST ) );
+ rPage.PageCreated( aSet );
+ }
+ else if (rId == "fonteffects")
+ {
+ aSet.Put( SfxUInt16Item( SID_DISABLE_CTL, DISABLE_CASEMAP ) );
+ rPage.PageCreated( aSet );
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx b/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx
new file mode 100644
index 0000000000..4c72d4d812
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_ShapeParagraph.cxx
@@ -0,0 +1,64 @@
+/* -*- 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 .
+ */
+
+#include <dlg_ShapeParagraph.hxx>
+
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <svx/flagsdef.hxx>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+ShapeParagraphDialog::ShapeParagraphDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr)
+ : SfxTabDialogController(pParent, "modules/schart/ui/paradialog.ui", "ParagraphDialog", pAttr)
+{
+ AddTabPage("labelTP_PARA_STD", RID_SVXPAGE_STD_PARAGRAPH);
+ AddTabPage("labelTP_PARA_ALIGN", RID_SVXPAGE_ALIGN_PARAGRAPH );
+ if (SvtCJKOptions::IsAsianTypographyEnabled())
+ {
+ AddTabPage("labelTP_PARA_ASIAN", RID_SVXPAGE_PARA_ASIAN);
+ }
+ else
+ {
+ RemoveTabPage("labelTP_PARA_ASIAN");
+ }
+ AddTabPage("labelTP_TABULATOR", RID_SVXPAGE_TABULATOR);
+}
+
+void ShapeParagraphDialog::PageCreated(const OUString& rId, SfxTabPage& rPage)
+{
+ if (rId == "labelTP_TABULATOR")
+ {
+ SfxAllItemSet aSet( *( GetInputSetImpl()->GetPool() ) );
+ TabulatorDisableFlags const nFlags(( TabulatorDisableFlags::TypeMask &~TabulatorDisableFlags::TypeLeft ) |
+ ( TabulatorDisableFlags::FillMask &~TabulatorDisableFlags::FillNone ));
+ aSet.Put( SfxUInt16Item( SID_SVXTABULATORTABPAGE_DISABLEFLAGS, static_cast<sal_uInt16>(nFlags)) );
+ rPage.PageCreated( aSet );
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/dlg_View3D.cxx b/chart2/source/controller/dialogs/dlg_View3D.cxx
new file mode 100644
index 0000000000..1891ffff67
--- /dev/null
+++ b/chart2/source/controller/dialogs/dlg_View3D.cxx
@@ -0,0 +1,81 @@
+/* -*- 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 .
+ */
+
+#include <dlg_View3D.hxx>
+#include <strings.hrc>
+#include <ResId.hxx>
+#include "tp_3D_SceneGeometry.hxx"
+#include "tp_3D_SceneAppearance.hxx"
+#include "tp_3D_SceneIllumination.hxx"
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <Diagram.hxx>
+
+namespace chart
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+sal_uInt16 View3DDialog::m_nLastPageId = 0;
+
+View3DDialog::View3DDialog(weld::Window* pParent, const rtl::Reference<::chart::ChartModel> & xChartModel)
+ : GenericDialogController(pParent, "modules/schart/ui/3dviewdialog.ui", "3DViewDialog")
+ , m_aControllerLocker(xChartModel)
+ , m_xTabControl(m_xBuilder->weld_notebook("tabcontrol"))
+{
+ rtl::Reference< Diagram > xSceneProperties = xChartModel->getFirstChartDiagram();
+
+ m_xTabControl->append_page("geometry", SchResId(STR_PAGE_PERSPECTIVE));
+ m_xGeometry.reset(new ThreeD_SceneGeometry_TabPage(m_xTabControl->get_page("geometry"), xSceneProperties, m_aControllerLocker));
+
+ m_xTabControl->append_page("appearance", SchResId(STR_PAGE_APPEARANCE));
+ m_xAppearance.reset(new ThreeD_SceneAppearance_TabPage(m_xTabControl->get_page("appearance"), xChartModel, m_aControllerLocker));
+
+ m_xTabControl->append_page("illumination", SchResId(STR_PAGE_ILLUMINATION));
+ m_xIllumination.reset(new ThreeD_SceneIllumination_TabPage(m_xTabControl->get_page("illumination"), m_xDialog.get(),
+ xSceneProperties, xChartModel));
+
+ m_xTabControl->connect_enter_page(LINK(this, View3DDialog, ActivatePageHdl));
+
+ m_xTabControl->set_current_page(m_nLastPageId);
+}
+
+IMPL_LINK(View3DDialog, ActivatePageHdl, const OUString&, rPage, void)
+{
+ if (rPage == "appearance")
+ m_xAppearance->ActivatePage();
+}
+
+View3DDialog::~View3DDialog()
+{
+ m_nLastPageId = m_xTabControl->get_current_page();
+}
+
+short View3DDialog::run()
+{
+ short nResult = GenericDialogController::run();
+ if (nResult == RET_OK && m_xGeometry)
+ m_xGeometry->commitPendingChanges();
+ return nResult;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_BarGeometry.cxx b/chart2/source/controller/dialogs/res_BarGeometry.cxx
new file mode 100644
index 0000000000..81d933b208
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_BarGeometry.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 .
+ */
+
+#include <res_BarGeometry.hxx>
+#include <ResId.hxx>
+#include <chart.hrc>
+
+namespace chart
+{
+BarGeometryResources::BarGeometryResources(weld::Builder* pBuilder)
+ : m_xFT_Geometry(pBuilder->weld_label("shapeft"))
+ , m_xLB_Geometry(pBuilder->weld_tree_view("shape"))
+{
+ for (size_t i = 0; i < std::size(CHART_TYPE); ++i)
+ m_xLB_Geometry->append_text(SchResId(CHART_TYPE[i]));
+ m_xLB_Geometry->set_size_request(-1, m_xLB_Geometry->get_height_rows(std::size(CHART_TYPE)));
+}
+
+void BarGeometryResources::connect_changed(const Link<weld::TreeView&, void>& rLink)
+{
+ m_xLB_Geometry->connect_changed(rLink);
+}
+
+void BarGeometryResources::set_visible(bool bShow)
+{
+ m_xFT_Geometry->set_visible(bShow);
+ m_xLB_Geometry->set_visible(bShow);
+}
+
+void BarGeometryResources::set_sensitive(bool bEnable)
+{
+ m_xFT_Geometry->set_sensitive(bEnable);
+ m_xLB_Geometry->set_sensitive(bEnable);
+}
+
+sal_Int32 BarGeometryResources::get_selected_index() const
+{
+ return m_xLB_Geometry->get_selected_index();
+}
+
+void BarGeometryResources::select(sal_Int32 nPos)
+{
+ if (nPos < m_xLB_Geometry->n_children())
+ m_xLB_Geometry->select(nPos);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_DataLabel.cxx b/chart2/source/controller/dialogs/res_DataLabel.cxx
new file mode 100644
index 0000000000..c3d755cf92
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_DataLabel.cxx
@@ -0,0 +1,388 @@
+/* -*- 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 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include "res_DataLabel.hxx"
+
+#include <TextDirectionListBox.hxx>
+#include <chartview/ChartSfxItemIds.hxx>
+#include "dlg_NumberFormat.hxx"
+
+#include <svx/numinf.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ilstitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/sdangitm.hxx>
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+
+namespace chart
+{
+
+namespace
+{
+
+const std::u16string_view our_aLBEntryMap[] = {u" ", u", ", u"; ", u"\n", u". "};
+
+bool lcl_ReadNumberFormatFromItemSet( const SfxItemSet& rSet, TypedWhichId<SfxUInt32Item> nValueWhich, TypedWhichId<SfxBoolItem> nSourceFormatWhich, sal_uInt32& rnFormatKeyOut, bool& rbSourceFormatOut, bool& rbSourceFormatMixedStateOut )
+{
+ bool bSet = false;
+ if( const SfxUInt32Item* pNumItem = rSet.GetItemIfSet( nValueWhich ) )
+ {
+ rnFormatKeyOut = pNumItem->GetValue();
+ bSet = true;
+ }
+
+ rbSourceFormatMixedStateOut=true;
+ if( const SfxBoolItem * pBoolItem = rSet.GetItemIfSet( nSourceFormatWhich ) )
+ {
+ rbSourceFormatOut = pBoolItem->GetValue();
+ rbSourceFormatMixedStateOut=false;
+ }
+ return bSet;
+}
+
+void lcl_setBoolItemToCheckBox(const SfxItemSet& rInAttrs, TypedWhichId<SfxBoolItem> nWhichId, weld::CheckButton& rCheckbox, weld::TriStateEnabled& rTriState)
+{
+ if( const SfxBoolItem* pPoolItem = rInAttrs.GetItemIfSet(nWhichId) )
+ {
+ rCheckbox.set_active(pPoolItem->GetValue());
+ rTriState.bTriStateEnabled = false;
+ }
+ else
+ {
+ rCheckbox.set_state(TRISTATE_INDET);
+ rTriState.bTriStateEnabled = true;
+ }
+}
+
+}//end anonymous namespace
+
+DataLabelResources::DataLabelResources(weld::Builder* pBuilder, weld::Window* pParent, const SfxItemSet& rInAttrs)
+ : m_pNumberFormatter(nullptr)
+ , m_bNumberFormatMixedState(true)
+ , m_bPercentFormatMixedState(true)
+ , m_nNumberFormatForValue(0)
+ , m_nNumberFormatForPercent(11)
+ , m_bSourceFormatMixedState(true)
+ , m_bPercentSourceMixedState(true)
+ , m_bSourceFormatForValue(true)
+ , m_bSourceFormatForPercent(true)
+ , m_pWindow(pParent)
+ , m_pPool(rInAttrs.GetPool())
+ , m_xCBNumber(pBuilder->weld_check_button("CB_VALUE_AS_NUMBER"))
+ , m_xPB_NumberFormatForValue(pBuilder->weld_button("PB_NUMBERFORMAT"))
+ , m_xCBPercent(pBuilder->weld_check_button("CB_VALUE_AS_PERCENTAGE"))
+ , m_xPB_NumberFormatForPercent(pBuilder->weld_button("PB_PERCENT_NUMBERFORMAT"))
+ , m_xFT_NumberFormatForPercent(pBuilder->weld_label("STR_DLG_NUMBERFORMAT_FOR_PERCENTAGE_VALUE"))
+ , m_xCBCategory(pBuilder->weld_check_button("CB_CATEGORY"))
+ , m_xCBSymbol(pBuilder->weld_check_button("CB_SYMBOL"))
+ , m_xCBDataSeries(pBuilder->weld_check_button("CB_DATA_SERIES_NAME"))
+ , m_xCBWrapText(pBuilder->weld_check_button("CB_WRAP_TEXT"))
+ , m_xLB_Separator(pBuilder->weld_combo_box("LB_TEXT_SEPARATOR"))
+ , m_xLB_LabelPlacement(pBuilder->weld_combo_box("LB_LABEL_PLACEMENT"))
+ , m_xBxOrientation(pBuilder->weld_widget("boxORIENTATION"))
+ , m_xFT_Dial(pBuilder->weld_label("CT_LABEL_DIAL"))
+ , m_xNF_Degrees(pBuilder->weld_metric_spin_button("NF_LABEL_DEGREES", FieldUnit::DEGREE))
+ , m_xBxTextDirection(pBuilder->weld_widget("boxTXT_DIRECTION"))
+ , m_aLB_TextDirection(pBuilder->weld_combo_box("LB_LABEL_TEXTDIR"))
+ , m_xDC_Dial(new svx::DialControl)
+ , m_xDC_DialWin(new weld::CustomWeld(*pBuilder, "CT_DIAL", *m_xDC_Dial))
+ , m_xCBCustomLeaderLines(pBuilder->weld_check_button("CB_CUSTOM_LEADER_LINES"))
+{
+ m_xDC_Dial->SetText(m_xFT_Dial->get_label());
+
+ //fill label placement list
+ std::map< sal_Int32, OUString > aPlacementToStringMap;
+ for( sal_Int32 nEnum=0; nEnum<m_xLB_LabelPlacement->get_count(); ++nEnum )
+ aPlacementToStringMap[nEnum] = m_xLB_LabelPlacement->get_text(static_cast<sal_uInt16>(nEnum));
+
+
+ std::vector< sal_Int32 > aAvailablePlacementList;
+ if( const SfxIntegerListItem* pPlacementsItem = rInAttrs.GetItemIfSet(SCHATTR_DATADESCR_AVAILABLE_PLACEMENTS) )
+ aAvailablePlacementList = pPlacementsItem->GetList();
+
+ m_xLB_LabelPlacement->clear();
+ for( size_t nN=0; nN<aAvailablePlacementList.size(); ++nN )
+ {
+ sal_uInt16 nListBoxPos = static_cast<sal_uInt16>( nN );
+ sal_Int32 nPlacement = aAvailablePlacementList[nN];
+ m_aPlacementToListBoxMap[nPlacement]=nListBoxPos;
+ m_aListBoxToPlacementMap[nListBoxPos]=nPlacement;
+ m_xLB_LabelPlacement->append_text( aPlacementToStringMap[nPlacement] );
+ }
+
+ //some click handler
+ m_xPB_NumberFormatForValue->connect_clicked( LINK( this, DataLabelResources, NumberFormatDialogHdl ) );
+ m_xPB_NumberFormatForPercent->connect_clicked( LINK( this, DataLabelResources, NumberFormatDialogHdl ) );
+ m_xCBNumber->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBPercent->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBCategory->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBSymbol->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBDataSeries->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBWrapText->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+ m_xCBCustomLeaderLines->connect_toggled( LINK( this, DataLabelResources, CheckHdl ));
+
+ m_bNumberFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, m_nNumberFormatForValue, m_bSourceFormatForValue, m_bSourceFormatMixedState );
+ m_bPercentFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_nNumberFormatForPercent, m_bSourceFormatForPercent , m_bPercentSourceMixedState);
+
+ if( const SfxBoolItem* pNoPercentValueItem = rInAttrs.GetItemIfSet(SCHATTR_DATADESCR_NO_PERCENTVALUE) )
+ {
+ bool bForbidPercentValue = pNoPercentValueItem->GetValue();
+ if( bForbidPercentValue )
+ m_xCBPercent->set_sensitive(false);
+ }
+
+ m_xDC_Dial->SetLinkedField(m_xNF_Degrees.get());
+}
+
+DataLabelResources::~DataLabelResources()
+{
+}
+
+void DataLabelResources::SetNumberFormatter( SvNumberFormatter* pFormatter )
+{
+ m_pNumberFormatter = pFormatter;
+}
+
+IMPL_LINK(DataLabelResources, NumberFormatDialogHdl, weld::Button&, rButton, void)
+{
+ if( !m_pPool || !m_pNumberFormatter )
+ {
+ OSL_FAIL("Missing item pool or number formatter");
+ return;
+ }
+
+ if (&rButton == m_xPB_NumberFormatForValue.get() && !m_xCBNumber->get_active())
+ {
+ m_xCBNumber->set_active(true);
+ m_aNumberState.bTriStateEnabled = false;
+ }
+ else if (&rButton == m_xPB_NumberFormatForPercent.get() && !m_xCBPercent->get_active())
+ {
+ m_xCBPercent->set_active(true);
+ m_aPercentState.bTriStateEnabled = false;
+ }
+
+ SfxItemSet aNumberSet = NumberFormatDialog::CreateEmptyItemSetForNumberFormatDialog( *m_pPool );
+ aNumberSet.Put (SvxNumberInfoItem( m_pNumberFormatter, SID_ATTR_NUMBERFORMAT_INFO));
+
+ bool bPercent = (&rButton == m_xPB_NumberFormatForPercent.get());
+
+ sal_uInt32& rnFormatKey = bPercent ? m_nNumberFormatForPercent : m_nNumberFormatForValue;
+ bool& rUseSourceFormat = bPercent ? m_bSourceFormatForPercent : m_bSourceFormatForValue;
+ bool& rbMixedState = bPercent ? m_bPercentFormatMixedState : m_bNumberFormatMixedState;
+ bool& rbSourceMixedState = bPercent ? m_bPercentSourceMixedState : m_bSourceFormatMixedState;
+
+ if(!rbMixedState)
+ aNumberSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, rnFormatKey ));
+ aNumberSet.Put( SfxBoolItem( SID_ATTR_NUMBERFORMAT_SOURCE, rUseSourceFormat ));
+
+ NumberFormatDialog aDlg(m_pWindow, aNumberSet);
+ if( bPercent )
+ aDlg.set_title(m_xFT_NumberFormatForPercent->get_label());
+ if (aDlg.run() != RET_OK)
+ return;
+
+ const SfxItemSet* pResult = aDlg.GetOutputItemSet();
+ if( pResult )
+ {
+ bool bOldSource = rUseSourceFormat;
+ sal_uInt32 nOldFormat = rnFormatKey;
+ bool bOldMixedState = rbMixedState || rbSourceMixedState;
+
+ rbMixedState = !lcl_ReadNumberFormatFromItemSet( *pResult, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, rnFormatKey, rUseSourceFormat, rbSourceMixedState );
+
+ //todo this maybe can be removed when the numberformatter dialog does handle mixed state for source format correctly
+ if( bOldMixedState && bOldSource == rUseSourceFormat && nOldFormat == rnFormatKey )
+ rbMixedState = rbSourceMixedState = true;
+ }
+}
+
+IMPL_LINK(DataLabelResources, CheckHdl, weld::Toggleable&, rToggle, void)
+{
+ if (&rToggle == m_xCBNumber.get())
+ m_aNumberState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBPercent.get())
+ m_aPercentState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBCategory.get())
+ m_aCategoryState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBSymbol.get())
+ m_aSymbolState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBDataSeries.get())
+ m_aDataSeriesState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBWrapText.get())
+ m_aWrapTextState.ButtonToggled(rToggle);
+ else if (&rToggle == m_xCBCustomLeaderLines.get())
+ m_aCustomLeaderLinesState.ButtonToggled(rToggle);
+ EnableControls();
+}
+
+void DataLabelResources::EnableControls()
+{
+ m_xCBSymbol->set_sensitive( m_xCBNumber->get_active() || (m_xCBPercent->get_active() && m_xCBPercent->get_sensitive())
+ || m_xCBCategory->get_active() || m_xCBDataSeries->get_active());
+
+ m_xCBWrapText->set_sensitive( m_xCBNumber->get_active() || (m_xCBPercent->get_active() && m_xCBPercent->get_sensitive())
+ || m_xCBCategory->get_active() || m_xCBDataSeries->get_active() );
+
+ // Enable or disable separator, placement and direction based on the check
+ // box states. Note that the check boxes are tri-state.
+ {
+ tools::Long nNumberOfCheckedLabelParts = 0;
+ if (m_xCBNumber->get_state() != TRISTATE_FALSE)
+ ++nNumberOfCheckedLabelParts;
+ if (m_xCBPercent->get_state() != TRISTATE_FALSE && m_xCBPercent->get_sensitive())
+ ++nNumberOfCheckedLabelParts;
+ if (m_xCBCategory->get_state() != TRISTATE_FALSE)
+ ++nNumberOfCheckedLabelParts;
+ if (m_xCBDataSeries->get_state() != TRISTATE_FALSE)
+ ++nNumberOfCheckedLabelParts;
+
+ m_xLB_Separator->set_sensitive( nNumberOfCheckedLabelParts > 1 );
+
+ bool bEnableTextDir = nNumberOfCheckedLabelParts > 0;
+ m_xBxTextDirection->set_sensitive( bEnableTextDir );
+ bool bEnablePlacement = nNumberOfCheckedLabelParts > 0 && m_xLB_LabelPlacement->get_count()>1;
+ m_xLB_LabelPlacement->set_sensitive( bEnablePlacement );
+ }
+
+ m_xPB_NumberFormatForValue->set_sensitive( m_pNumberFormatter && m_xCBNumber->get_active() );
+ m_xPB_NumberFormatForPercent->set_sensitive( m_pNumberFormatter && m_xCBPercent->get_active() && m_xCBPercent->get_sensitive() );
+
+ bool bEnableRotation = (m_xCBNumber->get_active() || m_xCBPercent->get_active()
+ || m_xCBCategory->get_active() || m_xCBDataSeries->get_active());
+ m_xBxOrientation->set_sensitive(bEnableRotation);
+}
+
+void DataLabelResources::FillItemSet( SfxItemSet* rOutAttrs ) const
+{
+ if( m_xCBNumber->get_active() )
+ {
+ if( !m_bNumberFormatMixedState )
+ rOutAttrs->Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, m_nNumberFormatForValue ));
+ if( !m_bSourceFormatMixedState )
+ rOutAttrs->Put( SfxBoolItem( SID_ATTR_NUMBERFORMAT_SOURCE, m_bSourceFormatForValue ));
+ }
+ if( m_xCBPercent->get_active() )
+ {
+ if( !m_bPercentFormatMixedState )
+ rOutAttrs->Put( SfxUInt32Item( SCHATTR_PERCENT_NUMBERFORMAT_VALUE, m_nNumberFormatForPercent ));
+ if( !m_bPercentSourceMixedState )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_bSourceFormatForPercent ));
+ }
+
+ if( m_xCBNumber->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_NUMBER, m_xCBNumber->get_active() ) );
+ if( m_xCBPercent->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_PERCENTAGE, m_xCBPercent->get_active() ) );
+ if( m_xCBCategory->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_CATEGORY, m_xCBCategory->get_active() ) );
+ if( m_xCBSymbol->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_SYMBOL, m_xCBSymbol->get_active()) );
+ if( m_xCBDataSeries->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME, m_xCBDataSeries->get_active()) );
+ if( m_xCBWrapText->get_state()!= TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_DATADESCR_WRAP_TEXT, m_xCBWrapText->get_active()) );
+ if( m_xCBCustomLeaderLines->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put(SfxBoolItem( SCHATTR_DATADESCR_CUSTOM_LEADER_LINES, m_xCBCustomLeaderLines->get_active()) );
+
+ auto const aSep = our_aLBEntryMap[m_xLB_Separator->get_active()];
+ rOutAttrs->Put( SfxStringItem( SCHATTR_DATADESCR_SEPARATOR, OUString(aSep)) );
+
+ std::map< sal_uInt16, sal_Int32 >::const_iterator aIt( m_aListBoxToPlacementMap.find(m_xLB_LabelPlacement->get_active()) );
+ if(aIt!=m_aListBoxToPlacementMap.end())
+ {
+ sal_Int32 nValue = aIt->second;
+ rOutAttrs->Put( SfxInt32Item( SCHATTR_DATADESCR_PLACEMENT, nValue ) );
+ }
+
+ if (m_aLB_TextDirection.get_active() != -1)
+ rOutAttrs->Put( SvxFrameDirectionItem( m_aLB_TextDirection.get_active_id(), EE_PARA_WRITINGDIR ) );
+
+ if( m_xDC_Dial->IsVisible() )
+ {
+ Degree100 nDegrees = m_xDC_Dial->GetRotation();
+ rOutAttrs->Put(SdrAngleItem( SCHATTR_TEXT_DEGREES, nDegrees ) );
+ }
+}
+
+void DataLabelResources::Reset(const SfxItemSet& rInAttrs)
+{
+ // default state
+ m_xCBSymbol->set_sensitive( false );
+
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_NUMBER, *m_xCBNumber, m_aNumberState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_PERCENTAGE, *m_xCBPercent, m_aPercentState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_CATEGORY, *m_xCBCategory, m_aCategoryState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_SYMBOL, *m_xCBSymbol, m_aSymbolState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_SHOW_DATA_SERIES_NAME, *m_xCBDataSeries, m_aDataSeriesState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_WRAP_TEXT, *m_xCBWrapText, m_aWrapTextState );
+ lcl_setBoolItemToCheckBox( rInAttrs, SCHATTR_DATADESCR_CUSTOM_LEADER_LINES, *m_xCBCustomLeaderLines, m_aCustomLeaderLinesState );
+
+ m_bNumberFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_SOURCE, m_nNumberFormatForValue, m_bSourceFormatForValue, m_bSourceFormatMixedState );
+ m_bPercentFormatMixedState = !lcl_ReadNumberFormatFromItemSet( rInAttrs, SCHATTR_PERCENT_NUMBERFORMAT_VALUE, SCHATTR_PERCENT_NUMBERFORMAT_SOURCE, m_nNumberFormatForPercent, m_bSourceFormatForPercent , m_bPercentSourceMixedState);
+
+ if( const SfxStringItem* pSeparatorItem = rInAttrs.GetItemIfSet(SCHATTR_DATADESCR_SEPARATOR) )
+ for(size_t i=0; i < std::size(our_aLBEntryMap); ++i )
+ {
+ if( our_aLBEntryMap[i] == pSeparatorItem->GetValue())
+ m_xLB_Separator->set_active( i );
+ }
+ else
+ m_xLB_Separator->set_active( 0 );
+
+ if( const SfxInt32Item* pPlacementItem = rInAttrs.GetItemIfSet(SCHATTR_DATADESCR_PLACEMENT) )
+ {
+ sal_Int32 nPlacement = pPlacementItem->GetValue();
+ std::map< sal_Int32, sal_uInt16 >::const_iterator aIt( m_aPlacementToListBoxMap.find(nPlacement) );
+ if(aIt!=m_aPlacementToListBoxMap.end())
+ {
+ sal_uInt16 nPos = aIt->second;
+ m_xLB_LabelPlacement->set_active( nPos );
+ }
+ else
+ m_xLB_LabelPlacement->set_active(-1);
+ }
+ else
+ m_xLB_LabelPlacement->set_active(-1);
+
+ if( const SvxFrameDirectionItem* pDirectionItem = rInAttrs.GetItemIfSet(EE_PARA_WRITINGDIR) )
+ m_aLB_TextDirection.set_active_id( pDirectionItem->GetValue() );
+
+ if( const SdrAngleItem* pAngleItem = rInAttrs.GetItemIfSet( SCHATTR_TEXT_DEGREES ) )
+ {
+ Degree100 nDegrees = pAngleItem->GetValue();
+ m_xDC_Dial->SetRotation( nDegrees );
+ }
+ else
+ m_xDC_Dial->SetRotation( 0_deg100 );
+
+ EnableControls();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_DataLabel.hxx b/chart2/source/controller/dialogs/res_DataLabel.hxx
new file mode 100644
index 0000000000..66a062d2ca
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_DataLabel.hxx
@@ -0,0 +1,101 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <svl/itemset.hxx>
+#include <svx/dialcontrol.hxx>
+#include <TextDirectionListBox.hxx>
+
+#include <map>
+
+class SvNumberFormatter;
+
+namespace chart
+{
+
+class DataLabelResources final
+{
+public:
+ DataLabelResources(weld::Builder* pBuilder, weld::Window* pParent, const SfxItemSet& rInAttrs);
+ ~DataLabelResources();
+
+ void FillItemSet(SfxItemSet* rOutAttrs) const;
+ void Reset(const SfxItemSet& rInAttrs);
+
+ void SetNumberFormatter( SvNumberFormatter* pFormatter );
+
+private:
+ std::map< sal_Int32, sal_uInt16 > m_aPlacementToListBoxMap;
+ std::map< sal_uInt16, sal_Int32 > m_aListBoxToPlacementMap;
+
+ SvNumberFormatter* m_pNumberFormatter;
+ bool m_bNumberFormatMixedState;
+ bool m_bPercentFormatMixedState;
+ sal_uInt32 m_nNumberFormatForValue;
+ sal_uInt32 m_nNumberFormatForPercent;
+
+ bool m_bSourceFormatMixedState;
+ bool m_bPercentSourceMixedState;
+ bool m_bSourceFormatForValue;
+ bool m_bSourceFormatForPercent;
+
+ weld::Window* m_pWindow;
+ SfxItemPool* m_pPool;
+
+ weld::TriStateEnabled m_aNumberState;
+ weld::TriStateEnabled m_aPercentState;
+ weld::TriStateEnabled m_aCategoryState;
+ weld::TriStateEnabled m_aSymbolState;
+ weld::TriStateEnabled m_aDataSeriesState;
+ weld::TriStateEnabled m_aWrapTextState;
+ weld::TriStateEnabled m_aCustomLeaderLinesState;
+
+ std::unique_ptr<weld::CheckButton> m_xCBNumber;
+ std::unique_ptr<weld::Button> m_xPB_NumberFormatForValue;
+ std::unique_ptr<weld::CheckButton> m_xCBPercent;
+ std::unique_ptr<weld::Button> m_xPB_NumberFormatForPercent;
+ std::unique_ptr<weld::Label> m_xFT_NumberFormatForPercent;
+ std::unique_ptr<weld::CheckButton> m_xCBCategory;
+ std::unique_ptr<weld::CheckButton> m_xCBSymbol;
+ std::unique_ptr<weld::CheckButton> m_xCBDataSeries;
+ std::unique_ptr<weld::CheckButton> m_xCBWrapText;
+
+ std::unique_ptr<weld::ComboBox> m_xLB_Separator;
+ std::unique_ptr<weld::ComboBox> m_xLB_LabelPlacement;
+
+ std::unique_ptr<weld::Widget> m_xBxOrientation;
+ std::unique_ptr<weld::Label> m_xFT_Dial;
+ std::unique_ptr<weld::MetricSpinButton> m_xNF_Degrees;
+
+ std::unique_ptr<weld::Widget> m_xBxTextDirection;
+
+ TextDirectionListBox m_aLB_TextDirection;
+ std::unique_ptr<svx::DialControl> m_xDC_Dial;
+ std::unique_ptr<weld::CustomWeld> m_xDC_DialWin;
+
+ std::unique_ptr<weld::CheckButton> m_xCBCustomLeaderLines;
+
+ DECL_LINK(NumberFormatDialogHdl, weld::Button&, void );
+ DECL_LINK(CheckHdl, weld::Toggleable&, void );
+ void EnableControls();
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_DataTableProperties.cxx b/chart2/source/controller/dialogs/res_DataTableProperties.cxx
new file mode 100644
index 0000000000..bf87b3e6b9
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_DataTableProperties.cxx
@@ -0,0 +1,111 @@
+/* -*- 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/.
+ */
+
+#include <res_DataTableProperties.hxx>
+
+#include <chartview/ChartSfxItemIds.hxx>
+#include <svl/eitem.hxx>
+
+using namespace css;
+
+namespace chart
+{
+DataTablePropertiesResources::DataTablePropertiesResources(weld::Builder& rBuilder)
+ : m_xCbHorizontalBorder(rBuilder.weld_check_button("horizontalBorderCB"))
+ , m_xCbVerticalBorder(rBuilder.weld_check_button("verticalBorderCB"))
+ , m_xCbOutilne(rBuilder.weld_check_button("outlineCB"))
+ , m_xCbKeys(rBuilder.weld_check_button("keysCB"))
+{
+}
+
+void DataTablePropertiesResources::setChecksSensitive(bool bSensitive)
+{
+ m_xCbHorizontalBorder->set_sensitive(bSensitive);
+ m_xCbVerticalBorder->set_sensitive(bSensitive);
+ m_xCbOutilne->set_sensitive(bSensitive);
+ m_xCbKeys->set_sensitive(bSensitive);
+}
+
+void DataTablePropertiesResources::initFromItemSet(const SfxItemSet& rInAttrs)
+{
+ const SfxPoolItem* pPoolItem = nullptr;
+ SfxItemState aState;
+
+ aState = rInAttrs.GetItemState(SCHATTR_DATA_TABLE_HORIZONTAL_BORDER, false, &pPoolItem);
+ if (aState == SfxItemState::DONTCARE)
+ {
+ m_xCbHorizontalBorder->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if (aState == SfxItemState::SET)
+ m_xCbHorizontalBorder->set_active(
+ static_cast<const SfxBoolItem*>(pPoolItem)->GetValue());
+ }
+
+ aState = rInAttrs.GetItemState(SCHATTR_DATA_TABLE_VERTICAL_BORDER, false, &pPoolItem);
+ if (aState == SfxItemState::DONTCARE)
+ {
+ m_xCbVerticalBorder->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if (aState == SfxItemState::SET)
+ m_xCbVerticalBorder->set_active(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue());
+ }
+
+ aState = rInAttrs.GetItemState(SCHATTR_DATA_TABLE_OUTLINE, false, &pPoolItem);
+ if (aState == SfxItemState::DONTCARE)
+ {
+ m_xCbOutilne->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if (aState == SfxItemState::SET)
+ m_xCbOutilne->set_active(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue());
+ }
+
+ aState = rInAttrs.GetItemState(SCHATTR_DATA_TABLE_KEYS, false, &pPoolItem);
+ if (aState == SfxItemState::DONTCARE)
+ {
+ m_xCbKeys->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if (aState == SfxItemState::SET)
+ m_xCbKeys->set_active(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue());
+ }
+}
+
+bool DataTablePropertiesResources::writeToItemSet(SfxItemSet& rOutAttrs) const
+{
+ if (m_xCbHorizontalBorder->get_state() != TRISTATE_INDET)
+ {
+ rOutAttrs.Put(
+ SfxBoolItem(SCHATTR_DATA_TABLE_HORIZONTAL_BORDER, m_xCbHorizontalBorder->get_active()));
+ }
+ if (m_xCbVerticalBorder->get_state() != TRISTATE_INDET)
+ {
+ rOutAttrs.Put(
+ SfxBoolItem(SCHATTR_DATA_TABLE_VERTICAL_BORDER, m_xCbVerticalBorder->get_active()));
+ }
+ if (m_xCbOutilne->get_state() != TRISTATE_INDET)
+ {
+ rOutAttrs.Put(SfxBoolItem(SCHATTR_DATA_TABLE_OUTLINE, m_xCbOutilne->get_active()));
+ }
+ if (m_xCbKeys->get_state() != TRISTATE_INDET)
+ {
+ rOutAttrs.Put(SfxBoolItem(SCHATTR_DATA_TABLE_KEYS, m_xCbKeys->get_active()));
+ }
+ return true;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_ErrorBar.cxx b/chart2/source/controller/dialogs/res_ErrorBar.cxx
new file mode 100644
index 0000000000..3eb875098b
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_ErrorBar.cxx
@@ -0,0 +1,716 @@
+/* -*- 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 .
+ */
+
+#include <res_ErrorBar.hxx>
+#include <bitmaps.hlst>
+#include <RangeSelectionHelper.hxx>
+#include <helpids.h>
+#include <chartview/ChartSfxItemIds.hxx>
+#include <vcl/weld.hxx>
+#include <ChartModel.hxx>
+
+#include <rtl/math.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <osl/diagnose.h>
+#include <svl/stritem.hxx>
+
+#define CHART_LB_FUNCTION_STD_ERROR 0
+#define CHART_LB_FUNCTION_STD_DEV 1
+#define CHART_LB_FUNCTION_VARIANCE 2
+#define CHART_LB_FUNCTION_ERROR_MARGIN 3
+
+using namespace ::com::sun::star;
+
+namespace
+{
+void lcl_enableRangeChoosing(bool bEnable, weld::DialogController* pController)
+{
+ weld::Window* pWeldDialog = pController->getDialog();
+ pWeldDialog->set_modal(!bEnable);
+ pWeldDialog->set_visible(!bEnable);
+}
+
+sal_uInt16 lcl_getLbEntryPosByErrorKind( SvxChartKindError eErrorKind )
+{
+ sal_uInt16 nResult = 0;
+ switch( eErrorKind )
+ {
+ // for these cases select the default in the list box
+ case SvxChartKindError::NONE:
+ case SvxChartKindError::Percent:
+ case SvxChartKindError::Const:
+ case SvxChartKindError::Range:
+ nResult = CHART_LB_FUNCTION_STD_DEV;
+ break;
+ case SvxChartKindError::Variant:
+ nResult = CHART_LB_FUNCTION_VARIANCE;
+ break;
+ case SvxChartKindError::Sigma:
+ nResult = CHART_LB_FUNCTION_STD_DEV;
+ break;
+ case SvxChartKindError::BigError:
+ nResult = CHART_LB_FUNCTION_ERROR_MARGIN;
+ break;
+ case SvxChartKindError::StdError:
+ nResult = CHART_LB_FUNCTION_STD_ERROR;
+ break;
+ }
+ return nResult;
+}
+} // anonymous namespace
+
+namespace chart
+{
+
+ErrorBarResources::ErrorBarResources(weld::Builder* pParent, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, bool bNoneAvailable,
+ tErrorBarType eType /* = ERROR_BAR_Y */ )
+ : m_eErrorKind( SvxChartKindError::NONE )
+ , m_eIndicate( SvxChartIndicate::Both )
+ , m_bErrorKindUnique( true )
+ , m_bIndicatorUnique( true )
+ , m_bRangePosUnique( true )
+ , m_bRangeNegUnique( true )
+ , m_eErrorBarType( eType )
+ , m_nConstDecimalDigits( 1 )
+ , m_nConstSpinSize( 1 )
+ , m_fPlusValue(0.0)
+ , m_fMinusValue(0.0)
+ , m_pController(pController)
+ , m_pCurrentRangeChoosingField( nullptr )
+ , m_bHasInternalDataProvider( true )
+ , m_bEnableDataTableDialog( true )
+ , m_xRbNone(pParent->weld_radio_button("RB_NONE"))
+ , m_xRbConst(pParent->weld_radio_button("RB_CONST"))
+ , m_xRbPercent(pParent->weld_radio_button("RB_PERCENT"))
+ , m_xRbFunction(pParent->weld_radio_button("RB_FUNCTION"))
+ , m_xRbRange(pParent->weld_radio_button("RB_RANGE"))
+ , m_xLbFunction(pParent->weld_combo_box("LB_FUNCTION"))
+ , m_xFlParameters(pParent->weld_frame("framePARAMETERS"))
+ , m_xBxPositive(pParent->weld_widget("boxPOSITIVE"))
+ , m_xMfPositive(pParent->weld_metric_spin_button("MF_POSITIVE", FieldUnit::NONE))
+ , m_xEdRangePositive(pParent->weld_entry("ED_RANGE_POSITIVE"))
+ , m_xIbRangePositive(pParent->weld_button("IB_RANGE_POSITIVE"))
+ , m_xBxNegative(pParent->weld_widget("boxNEGATIVE"))
+ , m_xMfNegative(pParent->weld_metric_spin_button("MF_NEGATIVE", FieldUnit::NONE))
+ , m_xEdRangeNegative(pParent->weld_entry("ED_RANGE_NEGATIVE"))
+ , m_xIbRangeNegative(pParent->weld_button("IB_RANGE_NEGATIVE"))
+ , m_xCbSyncPosNeg(pParent->weld_check_button("CB_SYN_POS_NEG"))
+ , m_xRbBoth(pParent->weld_radio_button("RB_BOTH"))
+ , m_xRbPositive(pParent->weld_radio_button("RB_POSITIVE"))
+ , m_xRbNegative(pParent->weld_radio_button("RB_NEGATIVE"))
+ , m_xFiBoth(pParent->weld_image("FI_BOTH"))
+ , m_xFiPositive(pParent->weld_image("FI_POSITIVE"))
+ , m_xFiNegative(pParent->weld_image("FI_NEGATIVE"))
+ , m_xUIStringPos(pParent->weld_label("STR_DATA_SELECT_RANGE_FOR_POSITIVE_ERRORBARS"))
+ , m_xUIStringNeg(pParent->weld_label("STR_DATA_SELECT_RANGE_FOR_NEGATIVE_ERRORBARS"))
+ , m_xUIStringRbRange(pParent->weld_label("STR_CONTROLTEXT_ERROR_BARS_FROM_DATA"))
+{
+ if( bNoneAvailable )
+ m_xRbNone->connect_toggled(LINK(this, ErrorBarResources, CategoryChosen));
+ else
+ m_xRbNone->hide();
+
+ m_xRbConst->connect_toggled( LINK( this, ErrorBarResources, CategoryChosen ));
+ m_xRbPercent->connect_toggled( LINK( this, ErrorBarResources, CategoryChosen ));
+ m_xRbFunction->connect_toggled( LINK( this, ErrorBarResources, CategoryChosen ));
+ m_xRbRange->connect_toggled( LINK( this, ErrorBarResources, CategoryChosen ));
+ m_xLbFunction->connect_changed( LINK( this, ErrorBarResources, CategoryChosen2 ));
+
+ m_xCbSyncPosNeg->set_active( false );
+ m_xCbSyncPosNeg->connect_toggled( LINK( this, ErrorBarResources, SynchronizePosAndNeg ));
+
+ m_xMfPositive->connect_value_changed( LINK( this, ErrorBarResources, PosValueChanged ));
+ m_xEdRangePositive->connect_changed( LINK( this, ErrorBarResources, RangeChanged ));
+ m_xEdRangeNegative->connect_changed( LINK( this, ErrorBarResources, RangeChanged ));
+
+ m_xRbPositive->connect_toggled( LINK( this, ErrorBarResources, IndicatorChanged ));
+ m_xRbNegative->connect_toggled( LINK( this, ErrorBarResources, IndicatorChanged ));
+ m_xRbBoth->connect_toggled( LINK( this, ErrorBarResources, IndicatorChanged ));
+
+ m_xIbRangePositive->connect_clicked( LINK( this, ErrorBarResources, ChooseRange ));
+ m_xIbRangeNegative->connect_clicked( LINK( this, ErrorBarResources, ChooseRange ));
+
+ FillValueSets();
+ Reset( rInAttrs );
+}
+
+ErrorBarResources::~ErrorBarResources()
+{
+}
+
+void ErrorBarResources::SetErrorBarType( tErrorBarType eNewType )
+{
+ if( m_eErrorBarType != eNewType )
+ {
+ m_eErrorBarType = eNewType;
+ FillValueSets();
+ }
+}
+
+void ErrorBarResources::SetChartDocumentForRangeChoosing(
+ const rtl::Reference<::chart::ChartModel> & xChartDocument )
+{
+ if( xChartDocument.is())
+ {
+ m_bHasInternalDataProvider = xChartDocument->hasInternalDataProvider();
+ uno::Reference< beans::XPropertySet > xProps( static_cast<cppu::OWeakObject*>(xChartDocument.get()), uno::UNO_QUERY );
+ if ( xProps.is() )
+ {
+ try
+ {
+ xProps->getPropertyValue("EnableDataTableDialog") >>= m_bEnableDataTableDialog;
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("chart2", "" );
+ }
+ }
+ }
+ m_apRangeSelectionHelper.reset( new RangeSelectionHelper( xChartDocument ));
+
+ // has internal data provider => rename "cell range" to "from data"
+ OSL_ASSERT(m_apRangeSelectionHelper);
+ if( m_bHasInternalDataProvider )
+ {
+ m_xRbRange->set_label(m_xUIStringRbRange->get_label());
+ m_xRbRange->set_help_id(HID_SCH_ERROR_BARS_FROM_DATA);
+ }
+
+ if( m_xRbRange->get_active())
+ {
+ isRangeFieldContentValid( *m_xEdRangePositive );
+ isRangeFieldContentValid( *m_xEdRangeNegative );
+ }
+}
+
+void ErrorBarResources::SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth )
+{
+ if( fMinorStepWidth < 0 )
+ fMinorStepWidth = -fMinorStepWidth;
+
+ sal_Int32 nExponent = static_cast< sal_Int32 >( ::rtl::math::approxFloor( log10( fMinorStepWidth )));
+ if( nExponent <= 0 )
+ {
+ // one digit precision more
+ m_nConstDecimalDigits = static_cast< sal_uInt16 >( (-nExponent) + 1 );
+ m_nConstSpinSize = 10;
+ }
+ else
+ {
+ m_nConstDecimalDigits = 0;
+ m_nConstSpinSize = static_cast< sal_Int64 >( pow( 10.0, static_cast<int>(nExponent) ));
+ }
+}
+
+void ErrorBarResources::UpdateControlStates()
+{
+ // function
+ bool bIsFunction = m_xRbFunction->get_active();
+ m_xLbFunction->set_sensitive( bIsFunction );
+
+ // range buttons
+ m_xRbRange->set_sensitive( !m_bHasInternalDataProvider || m_bEnableDataTableDialog );
+ bool bShowRange = m_xRbRange->get_active();
+ bool bCanChooseRange =
+ ( bShowRange &&
+ m_apRangeSelectionHelper &&
+ m_apRangeSelectionHelper->hasRangeSelection());
+
+ m_xMfPositive->set_visible( ! bShowRange );
+ m_xMfNegative->set_visible( ! bShowRange );
+
+ // use range but without range chooser => hide controls
+ m_xEdRangePositive->set_visible( bShowRange && ! m_bHasInternalDataProvider );
+ m_xIbRangePositive->set_visible( bCanChooseRange );
+ m_xEdRangeNegative->set_visible( bShowRange && ! m_bHasInternalDataProvider );
+ m_xIbRangeNegative->set_visible( bCanChooseRange );
+
+ bool bShowPosNegAndSync = ! (bShowRange && m_bHasInternalDataProvider);
+ m_xFlParameters->set_visible( bShowPosNegAndSync );
+
+ // unit for metric fields
+ bool bIsErrorMargin(
+ ( m_xRbFunction->get_active()) &&
+ ( m_xLbFunction->get_active() == CHART_LB_FUNCTION_ERROR_MARGIN ));
+ bool bIsPercentage( m_xRbPercent->get_active() || bIsErrorMargin );
+ FieldUnit eFieldUnit = FieldUnit::NONE;
+
+ if( bIsPercentage )
+ {
+ eFieldUnit = FieldUnit::PERCENT;
+ m_xMfPositive->set_digits( 1 );
+ m_xMfPositive->set_increments(10, 100, FieldUnit::NONE);
+ m_xMfNegative->set_digits( 1 );
+ m_xMfNegative->set_increments(10, 100, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xMfPositive->set_digits( m_nConstDecimalDigits );
+ m_xMfPositive->set_increments(m_nConstSpinSize, m_nConstSpinSize * 10, FieldUnit::NONE);
+ m_xMfNegative->set_digits( m_nConstDecimalDigits );
+ m_xMfNegative->set_increments(m_nConstSpinSize, m_nConstSpinSize * 10, FieldUnit::NONE);
+ }
+
+ sal_Int32 nPlusValue = static_cast< sal_Int32 >( m_fPlusValue * pow(10.0,m_xMfPositive->get_digits()) );
+ sal_Int32 nMinusValue = static_cast< sal_Int32 >( m_fMinusValue * pow(10.0,m_xMfNegative->get_digits()) );
+
+ m_xMfPositive->set_value(nPlusValue, FieldUnit::NONE);
+ m_xMfNegative->set_value(nMinusValue, FieldUnit::NONE);
+
+ m_xMfPositive->set_unit(eFieldUnit);
+ m_xMfNegative->set_unit(eFieldUnit);
+
+ // positive and negative value fields
+ bool bPosEnabled = ( m_xRbPositive->get_active() || m_xRbBoth->get_active());
+ bool bNegEnabled = ( m_xRbNegative->get_active() || m_xRbBoth->get_active());
+ if( !( bPosEnabled || bNegEnabled ))
+ {
+ // all three controls are not checked -> ambiguous state
+ bPosEnabled = true;
+ bNegEnabled = true;
+ }
+
+ // functions with only one parameter
+ bool bOneParameterCategory =
+ bIsErrorMargin || m_xRbPercent->get_active();
+ if( bOneParameterCategory )
+ {
+ m_xCbSyncPosNeg->set_active(true);
+ }
+
+ if( m_xCbSyncPosNeg->get_active())
+ {
+ bPosEnabled = true;
+ bNegEnabled = false;
+ }
+
+ // all functions except error margin take no arguments
+ if( m_xRbFunction->get_active() && ( m_xLbFunction->get_active() != CHART_LB_FUNCTION_ERROR_MARGIN ))
+ {
+ bPosEnabled = false;
+ bNegEnabled = false;
+ }
+
+ // enable/disable pos/neg fields
+ m_xBxPositive->set_sensitive( bPosEnabled );
+ m_xBxNegative->set_sensitive( bNegEnabled );
+ if( bShowRange )
+ {
+ m_xEdRangePositive->set_sensitive( bPosEnabled );
+ m_xIbRangePositive->set_sensitive( bPosEnabled );
+ m_xEdRangeNegative->set_sensitive( bNegEnabled );
+ m_xIbRangeNegative->set_sensitive( bNegEnabled );
+ }
+ else
+ {
+ m_xMfPositive->set_sensitive( bPosEnabled );
+ m_xMfNegative->set_sensitive( bNegEnabled );
+ }
+
+ m_xCbSyncPosNeg->set_sensitive( !bOneParameterCategory && ( bPosEnabled || bNegEnabled ));
+
+ // mark invalid entries in the range fields
+ if( bShowRange && ! m_bHasInternalDataProvider )
+ {
+ isRangeFieldContentValid( *m_xEdRangePositive );
+ isRangeFieldContentValid( *m_xEdRangeNegative );
+ }
+}
+
+IMPL_LINK_NOARG( ErrorBarResources, CategoryChosen2, weld::ComboBox&, void )
+{
+ CategoryChosen(*m_xRbConst);
+}
+
+IMPL_LINK_NOARG( ErrorBarResources, CategoryChosen, weld::Toggleable&, void )
+{
+ m_bErrorKindUnique = true;
+ SvxChartKindError eOldError = m_eErrorKind;
+
+ if( m_xRbNone->get_active())
+ m_eErrorKind = SvxChartKindError::NONE;
+ else if( m_xRbConst->get_active())
+ m_eErrorKind = SvxChartKindError::Const;
+ else if( m_xRbPercent->get_active())
+ m_eErrorKind = SvxChartKindError::Percent;
+ else if( m_xRbRange->get_active())
+ m_eErrorKind = SvxChartKindError::Range;
+ else if( m_xRbFunction->get_active())
+ {
+ switch( m_xLbFunction->get_active())
+ {
+ case CHART_LB_FUNCTION_STD_ERROR:
+ m_eErrorKind = SvxChartKindError::StdError; break;
+ case CHART_LB_FUNCTION_STD_DEV:
+ m_eErrorKind = SvxChartKindError::Sigma; break;
+ case CHART_LB_FUNCTION_VARIANCE:
+ m_eErrorKind = SvxChartKindError::Variant; break;
+ case CHART_LB_FUNCTION_ERROR_MARGIN:
+ m_eErrorKind = SvxChartKindError::BigError; break;
+ default:
+ m_bErrorKindUnique = false;
+ }
+ }
+ else
+ {
+ OSL_FAIL( "Unknown category chosen" );
+ m_bErrorKindUnique = false;
+ }
+
+ // changed to range
+ if( m_eErrorKind == SvxChartKindError::Range &&
+ eOldError != SvxChartKindError::Range )
+ {
+ m_xCbSyncPosNeg->set_active(
+ (!m_xEdRangePositive->get_text().isEmpty()) &&
+ m_xEdRangePositive->get_text() == m_xEdRangeNegative->get_text());
+ }
+ // changed from range
+ else if( m_eErrorKind != SvxChartKindError::Range &&
+ eOldError == SvxChartKindError::Range )
+ {
+ m_xCbSyncPosNeg->set_active( m_xMfPositive->get_value(FieldUnit::NONE) == m_xMfNegative->get_value(FieldUnit::NONE));
+ }
+
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(ErrorBarResources, SynchronizePosAndNeg, weld::Toggleable&, void)
+{
+ UpdateControlStates();
+ PosValueChanged( *m_xMfPositive );
+}
+
+IMPL_LINK_NOARG(ErrorBarResources, PosValueChanged, weld::MetricSpinButton&, void)
+{
+ if( m_xCbSyncPosNeg->get_active())
+ {
+ if( m_xRbRange->get_active())
+ {
+ m_xEdRangeNegative->set_text( m_xEdRangePositive->get_text());
+ m_bRangeNegUnique = m_bRangePosUnique;
+ }
+ else
+ m_xMfNegative->set_value(m_xMfPositive->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(ErrorBarResources, IndicatorChanged, weld::Toggleable&, void)
+{
+ m_bIndicatorUnique = true;
+ if( m_xRbBoth->get_active())
+ m_eIndicate = SvxChartIndicate::Both;
+ else if( m_xRbPositive->get_active())
+ m_eIndicate = SvxChartIndicate::Up;
+ else if( m_xRbNegative->get_active())
+ m_eIndicate = SvxChartIndicate::Down;
+ else
+ m_bIndicatorUnique = false;
+
+ UpdateControlStates();
+}
+
+IMPL_LINK(ErrorBarResources, ChooseRange, weld::Button&, rButton, void)
+{
+ OSL_ASSERT(m_apRangeSelectionHelper);
+ if (!m_apRangeSelectionHelper)
+ return;
+ OSL_ASSERT( m_pCurrentRangeChoosingField == nullptr );
+
+ OUString aUIString;
+
+ if (&rButton == m_xIbRangePositive.get())
+ {
+ m_pCurrentRangeChoosingField = m_xEdRangePositive.get();
+ aUIString = m_xUIStringPos->get_label();
+ }
+ else
+ {
+ m_pCurrentRangeChoosingField = m_xEdRangeNegative.get();
+ aUIString = m_xUIStringNeg->get_label();
+ }
+
+ lcl_enableRangeChoosing(true, m_pController);
+ m_apRangeSelectionHelper->chooseRange(
+ m_pCurrentRangeChoosingField->get_text(),
+ aUIString, *this );
+}
+
+IMPL_LINK( ErrorBarResources, RangeChanged, weld::Entry&, rEdit, void )
+{
+ if( &rEdit == m_xEdRangePositive.get() )
+ {
+ m_bRangePosUnique = true;
+ PosValueChanged( *m_xMfPositive );
+ }
+ else
+ {
+ m_bRangeNegUnique = true;
+ }
+
+ isRangeFieldContentValid( rEdit );
+}
+
+void ErrorBarResources::Reset(const SfxItemSet& rInAttrs)
+{
+ const SfxPoolItem *pPoolItem = nullptr;
+
+ // category
+ m_eErrorKind = SvxChartKindError::NONE;
+ SfxItemState aState = rInAttrs.GetItemState( SCHATTR_STAT_KIND_ERROR, true, &pPoolItem );
+ m_bErrorKindUnique = ( aState != SfxItemState::DONTCARE );
+
+ if( aState == SfxItemState::SET )
+ m_eErrorKind = static_cast<const SvxChartKindErrorItem*>(pPoolItem)->GetValue();
+
+ m_xLbFunction->set_active( lcl_getLbEntryPosByErrorKind( m_eErrorKind ));
+
+ if( m_bErrorKindUnique )
+ {
+ switch( m_eErrorKind )
+ {
+ case SvxChartKindError::NONE:
+ m_xRbNone->set_active(true);
+ break;
+ case SvxChartKindError::Percent:
+ m_xRbPercent->set_active(true);
+ break;
+ case SvxChartKindError::Const:
+ m_xRbConst->set_active(true);
+ break;
+ case SvxChartKindError::StdError:
+ case SvxChartKindError::Variant:
+ case SvxChartKindError::Sigma:
+ case SvxChartKindError::BigError:
+ m_xRbFunction->set_active(true);
+ break;
+ case SvxChartKindError::Range:
+ m_xRbRange->set_active(true);
+ break;
+ }
+ }
+ else
+ {
+ m_xRbNone->set_active( false );
+ m_xRbConst->set_active( false );
+ m_xRbPercent->set_active( false );
+ m_xRbFunction->set_active( false );
+ }
+
+ // parameters
+ if( const SvxDoubleItem* pDoubleItem = rInAttrs.GetItemIfSet( SCHATTR_STAT_CONSTPLUS ) )
+ {
+ m_fPlusValue = pDoubleItem->GetValue();
+ }
+
+ if( const SvxDoubleItem* pStatItem = rInAttrs.GetItemIfSet( SCHATTR_STAT_CONSTMINUS ) )
+ {
+ m_fMinusValue = pStatItem->GetValue();
+
+ if( m_eErrorKind != SvxChartKindError::Range &&
+ m_fPlusValue == m_fMinusValue )
+ m_xCbSyncPosNeg->set_active(true);
+ }
+
+ // indicator
+ aState = rInAttrs.GetItemState( SCHATTR_STAT_INDICATE, true, &pPoolItem );
+ m_bIndicatorUnique = ( aState != SfxItemState::DONTCARE );
+ if( aState == SfxItemState::SET)
+ m_eIndicate = static_cast<const SvxChartIndicateItem *>(pPoolItem)->GetValue();
+
+ if( m_bIndicatorUnique )
+ {
+ switch( m_eIndicate )
+ {
+ case SvxChartIndicate::NONE :
+ // no longer used, use both as default
+ m_eIndicate = SvxChartIndicate::Both;
+ [[fallthrough]]; // to BOTH
+ case SvxChartIndicate::Both :
+ m_xRbBoth->set_active(true); break;
+ case SvxChartIndicate::Up :
+ m_xRbPositive->set_active(true); break;
+ case SvxChartIndicate::Down :
+ m_xRbNegative->set_active(true); break;
+ }
+ }
+ else
+ {
+ m_xRbBoth->set_active( false );
+ m_xRbPositive->set_active( false );
+ m_xRbNegative->set_active( false );
+ }
+
+ // ranges
+ aState = rInAttrs.GetItemState( SCHATTR_STAT_RANGE_POS, true, &pPoolItem );
+ m_bRangePosUnique = ( aState != SfxItemState::DONTCARE );
+ if( aState == SfxItemState::SET )
+ {
+ OUString sRangePositive = static_cast< const SfxStringItem * >( pPoolItem )->GetValue();
+ m_xEdRangePositive->set_text( sRangePositive );
+ }
+
+ aState = rInAttrs.GetItemState( SCHATTR_STAT_RANGE_NEG, true, &pPoolItem );
+ m_bRangeNegUnique = ( aState != SfxItemState::DONTCARE );
+ if( aState == SfxItemState::SET )
+ {
+ OUString sRangeNegative = static_cast< const SfxStringItem * >( pPoolItem )->GetValue();
+ m_xEdRangeNegative->set_text( sRangeNegative );
+ if( m_eErrorKind == SvxChartKindError::Range &&
+ !sRangeNegative.isEmpty() &&
+ sRangeNegative == m_xEdRangePositive->get_text() )
+ m_xCbSyncPosNeg->set_active(true);
+ }
+
+ UpdateControlStates();
+}
+
+void ErrorBarResources::FillItemSet(SfxItemSet& rOutAttrs) const
+{
+ if( m_bErrorKindUnique )
+ rOutAttrs.Put( SvxChartKindErrorItem( m_eErrorKind, SCHATTR_STAT_KIND_ERROR ));
+ if( m_bIndicatorUnique )
+ rOutAttrs.Put( SvxChartIndicateItem( m_eIndicate, SCHATTR_STAT_INDICATE ));
+
+ if( m_bErrorKindUnique )
+ {
+ if( m_eErrorKind == SvxChartKindError::Range )
+ {
+ OUString aPosRange;
+ OUString aNegRange;
+ if( m_bHasInternalDataProvider )
+ {
+ // the strings aPosRange/aNegRange have to be set to a non-empty
+ // arbitrary string to generate error-bar sequences
+ aPosRange = "x";
+ aNegRange = aPosRange;
+ }
+ else
+ {
+ aPosRange = m_xEdRangePositive->get_text();
+ if( m_xCbSyncPosNeg->get_active())
+ aNegRange = aPosRange;
+ else
+ aNegRange = m_xEdRangeNegative->get_text();
+ }
+
+ if( m_bRangePosUnique )
+ rOutAttrs.Put( SfxStringItem( SCHATTR_STAT_RANGE_POS, aPosRange ));
+ if( m_bRangeNegUnique )
+ rOutAttrs.Put( SfxStringItem( SCHATTR_STAT_RANGE_NEG, aNegRange ));
+ }
+ else if( m_eErrorKind == SvxChartKindError::Const ||
+ m_eErrorKind == SvxChartKindError::Percent ||
+ m_eErrorKind == SvxChartKindError::BigError )
+ {
+ double fPosValue = static_cast< double >( m_xMfPositive->get_value(FieldUnit::NONE)) /
+ pow( 10.0, m_xMfPositive->get_digits());
+ double fNegValue = 0.0;
+
+ if( m_xCbSyncPosNeg->get_active())
+ fNegValue = fPosValue;
+ else
+ fNegValue = static_cast< double >( m_xMfNegative->get_value(FieldUnit::NONE)) /
+ pow( 10.0, m_xMfNegative->get_digits());
+
+ rOutAttrs.Put( SvxDoubleItem( fPosValue, SCHATTR_STAT_CONSTPLUS ));
+ rOutAttrs.Put( SvxDoubleItem( fNegValue, SCHATTR_STAT_CONSTMINUS ));
+ }
+ }
+
+ rOutAttrs.Put( SfxBoolItem( SCHATTR_STAT_ERRORBAR_TYPE , m_eErrorBarType == ERROR_BAR_Y ));
+}
+
+void ErrorBarResources::FillValueSets()
+{
+ if( m_eErrorBarType == ERROR_BAR_Y )
+ {
+ m_xFiNegative->set_from_icon_name(BMP_INDICATE_DOWN);
+ m_xFiPositive->set_from_icon_name(BMP_INDICATE_UP);
+ m_xFiBoth->set_from_icon_name(BMP_INDICATE_BOTH_VERTI);
+ }
+ else if( m_eErrorBarType == ERROR_BAR_X )
+ {
+ m_xFiNegative->set_from_icon_name(BMP_INDICATE_LEFT);
+ m_xFiPositive->set_from_icon_name(BMP_INDICATE_RIGHT);
+ m_xFiBoth->set_from_icon_name(BMP_INDICATE_BOTH_HORI);
+ }
+}
+
+void ErrorBarResources::listeningFinished(
+ const OUString & rNewRange )
+{
+ OSL_ASSERT(m_apRangeSelectionHelper);
+ if (!m_apRangeSelectionHelper)
+ return;
+
+ // rNewRange becomes invalid after removing the listener
+ OUString aRange( rNewRange );
+
+ // stop listening
+ m_apRangeSelectionHelper->stopRangeListening();
+
+ // change edit field
+// if( m_pParentWindow )
+// {
+// m_pParentWindow->ToTop();
+// m_pParentWindow->grab_focus();
+// }
+
+ if( m_pCurrentRangeChoosingField )
+ {
+ m_pCurrentRangeChoosingField->set_text( aRange );
+ m_pCurrentRangeChoosingField->grab_focus();
+ PosValueChanged( *m_xMfPositive );
+ }
+
+ m_pCurrentRangeChoosingField = nullptr;
+
+ UpdateControlStates();
+ lcl_enableRangeChoosing(false, m_pController);
+}
+
+void ErrorBarResources::disposingRangeSelection()
+{
+ OSL_ASSERT(m_apRangeSelectionHelper);
+ if (m_apRangeSelectionHelper)
+ m_apRangeSelectionHelper->stopRangeListening( false );
+}
+
+void ErrorBarResources::isRangeFieldContentValid(weld::Entry& rEdit)
+{
+ OUString aRange( rEdit.get_text());
+ bool bIsValid = ( aRange.isEmpty() ) ||
+ ( m_apRangeSelectionHelper &&
+ m_apRangeSelectionHelper->verifyCellRange( aRange ));
+
+ if( bIsValid || !rEdit.get_sensitive())
+ {
+ rEdit.set_message_type(weld::EntryMessageType::Normal);
+ }
+ else
+ {
+ rEdit.set_message_type(weld::EntryMessageType::Error);
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_LegendPosition.cxx b/chart2/source/controller/dialogs/res_LegendPosition.cxx
new file mode 100644
index 0000000000..1562fcc719
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_LegendPosition.cxx
@@ -0,0 +1,244 @@
+/* -*- 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 .
+ */
+
+#include <res_LegendPosition.hxx>
+#include <ChartModelHelper.hxx>
+#include <Legend.hxx>
+#include <LegendHelper.hxx>
+#include <ChartModel.hxx>
+#include <Diagram.hxx>
+
+#include <com/sun/star/chart2/LegendPosition.hpp>
+#include <com/sun/star/chart/ChartLegendExpansion.hpp>
+
+//itemset stuff
+#include <chartview/ChartSfxItemIds.hxx>
+#include <svl/intitem.hxx>
+#include <svl/eitem.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <utility>
+#include <vcl/weld.hxx>
+
+namespace chart
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+LegendPositionResources::LegendPositionResources(weld::Builder& rBuilder)
+ : m_xRbtLeft(rBuilder.weld_radio_button("left"))
+ , m_xRbtRight(rBuilder.weld_radio_button("right"))
+ , m_xRbtTop(rBuilder.weld_radio_button("top"))
+ , m_xRbtBottom(rBuilder.weld_radio_button("bottom"))
+{
+ impl_setRadioButtonToggleHdl();
+}
+
+LegendPositionResources::LegendPositionResources(weld::Builder& rBuilder,
+ uno::Reference< uno::XComponentContext > xCC)
+ : m_xCC(std::move(xCC))
+ , m_xCbxShow(rBuilder.weld_check_button("show"))
+ , m_xRbtLeft(rBuilder.weld_radio_button("left"))
+ , m_xRbtRight(rBuilder.weld_radio_button("right"))
+ , m_xRbtTop(rBuilder.weld_radio_button("top"))
+ , m_xRbtBottom(rBuilder.weld_radio_button("bottom"))
+{
+ m_xCbxShow->connect_toggled( LINK( this, LegendPositionResources, PositionEnableHdl ) );
+ impl_setRadioButtonToggleHdl();
+}
+
+void LegendPositionResources::impl_setRadioButtonToggleHdl()
+{
+ m_xRbtLeft->connect_toggled( LINK( this, LegendPositionResources, PositionChangeHdl ) );
+ m_xRbtTop->connect_toggled( LINK( this, LegendPositionResources, PositionChangeHdl ) );
+ m_xRbtRight->connect_toggled( LINK( this, LegendPositionResources, PositionChangeHdl ) );
+ m_xRbtBottom->connect_toggled( LINK( this, LegendPositionResources, PositionChangeHdl ) );
+}
+
+LegendPositionResources::~LegendPositionResources()
+{
+}
+
+void LegendPositionResources::writeToResources( const rtl::Reference<::chart::ChartModel>& xChartModel )
+{
+ try
+ {
+ rtl::Reference< Diagram > xDiagram = xChartModel->getFirstChartDiagram();
+ rtl::Reference< Legend > xLegend = xDiagram->getLegend2();
+ if( xLegend.is() )
+ {
+ //show
+ bool bShowLegend = false;
+ xLegend->getPropertyValue( "Show" ) >>= bShowLegend;
+ if (m_xCbxShow)
+ m_xCbxShow->set_active( bShowLegend );
+ PositionEnable();
+
+ //position
+ chart2::LegendPosition ePos;
+ xLegend->getPropertyValue( "AnchorPosition" ) >>= ePos;
+ switch( ePos )
+ {
+ case chart2::LegendPosition_LINE_START:
+ m_xRbtLeft->set_active(true);
+ break;
+ case chart2::LegendPosition_PAGE_START:
+ m_xRbtTop->set_active(true);
+ break;
+ case chart2::LegendPosition_PAGE_END:
+ m_xRbtBottom->set_active(true);
+ break;
+ case chart2::LegendPosition_LINE_END:
+ default:
+ m_xRbtRight->set_active(true);
+ break;
+ }
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+void LegendPositionResources::writeToModel( const rtl::Reference<::chart::ChartModel>& xChartModel ) const
+{
+ try
+ {
+ bool bShowLegend = m_xCbxShow && m_xCbxShow->get_active();
+ ChartModel& rModel = *xChartModel;
+ rtl::Reference< Legend > xProp = LegendHelper::getLegend(rModel, m_xCC, bShowLegend);
+ if( xProp.is() )
+ {
+ //show
+ xProp->setPropertyValue( "Show" , uno::Any( bShowLegend ));
+
+ //position
+ chart2::LegendPosition eNewPos;
+ css::chart::ChartLegendExpansion eExp = css::chart::ChartLegendExpansion_HIGH;
+
+ if( m_xRbtLeft->get_active() )
+ eNewPos = chart2::LegendPosition_LINE_START;
+ else if( m_xRbtRight->get_active() )
+ {
+ eNewPos = chart2::LegendPosition_LINE_END;
+ }
+ else if( m_xRbtTop->get_active() )
+ {
+ eNewPos = chart2::LegendPosition_PAGE_START;
+ eExp = css::chart::ChartLegendExpansion_WIDE;
+ }
+ else if( m_xRbtBottom->get_active() )
+ {
+ eNewPos = chart2::LegendPosition_PAGE_END;
+ eExp = css::chart::ChartLegendExpansion_WIDE;
+ }
+
+ xProp->setPropertyValue( "AnchorPosition" , uno::Any( eNewPos ));
+ xProp->setPropertyValue( "Expansion" , uno::Any( eExp ));
+ xProp->setPropertyValue( "RelativePosition" , uno::Any());
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2" );
+ }
+}
+
+IMPL_LINK_NOARG(LegendPositionResources, PositionEnableHdl, weld::Toggleable&, void)
+{
+ PositionEnable();
+}
+
+void LegendPositionResources::PositionEnable()
+{
+ bool bEnable = !m_xCbxShow || m_xCbxShow->get_active();
+
+ m_xRbtLeft->set_sensitive( bEnable );
+ m_xRbtTop->set_sensitive( bEnable );
+ m_xRbtRight->set_sensitive( bEnable );
+ m_xRbtBottom->set_sensitive( bEnable );
+
+ m_aChangeLink.Call(nullptr);
+}
+
+void LegendPositionResources::initFromItemSet( const SfxItemSet& rInAttrs )
+{
+ if( const SfxInt32Item* pPosItem = rInAttrs.GetItemIfSet( SCHATTR_LEGEND_POS ) )
+ {
+ chart2::LegendPosition nLegendPosition = static_cast<chart2::LegendPosition>(pPosItem->GetValue());
+ switch( nLegendPosition )
+ {
+ case chart2::LegendPosition_LINE_START:
+ m_xRbtLeft->set_active(true);
+ break;
+ case chart2::LegendPosition_PAGE_START:
+ m_xRbtTop->set_active(true);
+ break;
+ case chart2::LegendPosition_LINE_END:
+ m_xRbtRight->set_active(true);
+ break;
+ case chart2::LegendPosition_PAGE_END:
+ m_xRbtBottom->set_active(true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ const SfxBoolItem* pShowItem;
+ if( m_xCbxShow && (pShowItem = rInAttrs.GetItemIfSet( SCHATTR_LEGEND_SHOW )) )
+ {
+ m_xCbxShow->set_active(pShowItem->GetValue());
+ }
+}
+
+void LegendPositionResources::writeToItemSet( SfxItemSet& rOutAttrs ) const
+{
+ chart2::LegendPosition nLegendPosition = chart2::LegendPosition_LINE_END;
+ if( m_xRbtLeft->get_active() )
+ nLegendPosition = chart2::LegendPosition_LINE_START;
+ else if( m_xRbtTop->get_active() )
+ nLegendPosition = chart2::LegendPosition_PAGE_START;
+ else if( m_xRbtRight->get_active() )
+ nLegendPosition = chart2::LegendPosition_LINE_END;
+ else if( m_xRbtBottom->get_active() )
+ nLegendPosition = chart2::LegendPosition_PAGE_END;
+ rOutAttrs.Put( SfxInt32Item(SCHATTR_LEGEND_POS, static_cast<sal_Int32>(nLegendPosition) ) );
+
+ rOutAttrs.Put( SfxBoolItem(SCHATTR_LEGEND_SHOW, !m_xCbxShow || m_xCbxShow->get_active()) );
+}
+
+IMPL_LINK (LegendPositionResources, PositionChangeHdl, weld::Toggleable&, rRadio, void)
+{
+ //for each radio click there are coming two change events
+ //first uncheck of previous button -> ignore that call
+ //the second call gives the check of the new button
+ if( rRadio.get_active() )
+ m_aChangeLink.Call(nullptr);
+}
+
+void LegendPositionResources::SetChangeHdl( const Link<LinkParamNone*,void>& rLink )
+{
+ m_aChangeLink = rLink;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_Titles.cxx b/chart2/source/controller/dialogs/res_Titles.cxx
new file mode 100644
index 0000000000..59b0f00b9b
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_Titles.cxx
@@ -0,0 +1,132 @@
+/* -*- 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 .
+ */
+
+#include <res_Titles.hxx>
+#include <TitleDialogData.hxx>
+#include <vcl/weld.hxx>
+
+namespace chart
+{
+TitleResources::TitleResources(weld::Builder& rBuilder, bool bShowSecondaryAxesTitle)
+ : m_xFT_Main(rBuilder.weld_label("labelMainTitle"))
+ , m_xFT_Sub(rBuilder.weld_label("labelSubTitle"))
+ , m_xEd_Main(rBuilder.weld_entry("maintitle"))
+ , m_xEd_Sub(rBuilder.weld_entry("subtitle"))
+ , m_xFT_XAxis(rBuilder.weld_label("labelPrimaryXaxis"))
+ , m_xFT_YAxis(rBuilder.weld_label("labelPrimaryYaxis"))
+ , m_xFT_ZAxis(rBuilder.weld_label("labelPrimaryZaxis"))
+ , m_xEd_XAxis(rBuilder.weld_entry("primaryXaxis"))
+ , m_xEd_YAxis(rBuilder.weld_entry("primaryYaxis"))
+ , m_xEd_ZAxis(rBuilder.weld_entry("primaryZaxis"))
+ , m_xFT_SecondaryXAxis(rBuilder.weld_label("labelSecondaryXAxis"))
+ , m_xFT_SecondaryYAxis(rBuilder.weld_label("labelSecondaryYAxis"))
+ , m_xEd_SecondaryXAxis(rBuilder.weld_entry("secondaryXaxis"))
+ , m_xEd_SecondaryYAxis(rBuilder.weld_entry("secondaryYaxis"))
+{
+ m_xFT_SecondaryXAxis->set_visible(bShowSecondaryAxesTitle);
+ m_xFT_SecondaryYAxis->set_visible(bShowSecondaryAxesTitle);
+ m_xEd_SecondaryXAxis->set_visible(bShowSecondaryAxesTitle);
+ m_xEd_SecondaryYAxis->set_visible(bShowSecondaryAxesTitle);
+}
+
+TitleResources::~TitleResources() {}
+
+void TitleResources::connect_changed(const Link<weld::Entry&, void>& rLink)
+{
+ m_xEd_Main->connect_changed(rLink);
+ m_xEd_Sub->connect_changed(rLink);
+ m_xEd_XAxis->connect_changed(rLink);
+ m_xEd_YAxis->connect_changed(rLink);
+ m_xEd_ZAxis->connect_changed(rLink);
+ m_xEd_SecondaryXAxis->connect_changed(rLink);
+ m_xEd_SecondaryYAxis->connect_changed(rLink);
+}
+
+bool TitleResources::get_value_changed_from_saved() const
+{
+ return m_xEd_Main->get_value_changed_from_saved() || m_xEd_Sub->get_value_changed_from_saved()
+ || m_xEd_XAxis->get_value_changed_from_saved()
+ || m_xEd_YAxis->get_value_changed_from_saved()
+ || m_xEd_ZAxis->get_value_changed_from_saved()
+ || m_xEd_SecondaryXAxis->get_value_changed_from_saved()
+ || m_xEd_SecondaryYAxis->get_value_changed_from_saved();
+}
+
+void TitleResources::save_value()
+{
+ m_xEd_Main->save_value();
+ m_xEd_Sub->save_value();
+ m_xEd_XAxis->save_value();
+ m_xEd_YAxis->save_value();
+ m_xEd_ZAxis->save_value();
+ m_xEd_SecondaryXAxis->save_value();
+ m_xEd_SecondaryYAxis->save_value();
+}
+
+void TitleResources::writeToResources(const TitleDialogData& rInput)
+{
+ m_xFT_Main->set_sensitive(rInput.aPossibilityList[0]);
+ m_xFT_Sub->set_sensitive(rInput.aPossibilityList[1]);
+ m_xFT_XAxis->set_sensitive(rInput.aPossibilityList[2]);
+ m_xFT_YAxis->set_sensitive(rInput.aPossibilityList[3]);
+ m_xFT_ZAxis->set_sensitive(rInput.aPossibilityList[4]);
+ m_xFT_SecondaryXAxis->set_sensitive(rInput.aPossibilityList[5]);
+ m_xFT_SecondaryYAxis->set_sensitive(rInput.aPossibilityList[6]);
+
+ m_xEd_Main->set_sensitive(rInput.aPossibilityList[0]);
+ m_xEd_Sub->set_sensitive(rInput.aPossibilityList[1]);
+ m_xEd_XAxis->set_sensitive(rInput.aPossibilityList[2]);
+ m_xEd_YAxis->set_sensitive(rInput.aPossibilityList[3]);
+ m_xEd_ZAxis->set_sensitive(rInput.aPossibilityList[4]);
+ m_xEd_SecondaryXAxis->set_sensitive(rInput.aPossibilityList[5]);
+ m_xEd_SecondaryYAxis->set_sensitive(rInput.aPossibilityList[6]);
+
+ m_xEd_Main->set_text(rInput.aTextList[0]);
+ m_xEd_Sub->set_text(rInput.aTextList[1]);
+ m_xEd_XAxis->set_text(rInput.aTextList[2]);
+ m_xEd_YAxis->set_text(rInput.aTextList[3]);
+ m_xEd_ZAxis->set_text(rInput.aTextList[4]);
+ m_xEd_SecondaryXAxis->set_text(rInput.aTextList[5]);
+ m_xEd_SecondaryYAxis->set_text(rInput.aTextList[6]);
+}
+
+void TitleResources::readFromResources(TitleDialogData& rOutput)
+{
+ sal_Bool* pExistenceList = rOutput.aExistenceList.getArray();
+ pExistenceList[0] = !m_xEd_Main->get_text().isEmpty();
+ pExistenceList[1] = !m_xEd_Sub->get_text().isEmpty();
+ pExistenceList[2] = !m_xEd_XAxis->get_text().isEmpty();
+ pExistenceList[3] = !m_xEd_YAxis->get_text().isEmpty();
+ pExistenceList[4] = !m_xEd_ZAxis->get_text().isEmpty();
+ pExistenceList[5] = !m_xEd_SecondaryXAxis->get_text().isEmpty();
+ pExistenceList[6] = !m_xEd_SecondaryYAxis->get_text().isEmpty();
+
+ auto pTextList = rOutput.aTextList.getArray();
+ pTextList[0] = m_xEd_Main->get_text();
+ pTextList[1] = m_xEd_Sub->get_text();
+ pTextList[2] = m_xEd_XAxis->get_text();
+ pTextList[3] = m_xEd_YAxis->get_text();
+ pTextList[4] = m_xEd_ZAxis->get_text();
+ pTextList[5] = m_xEd_SecondaryXAxis->get_text();
+ pTextList[6] = m_xEd_SecondaryYAxis->get_text();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_Trendline.cxx b/chart2/source/controller/dialogs/res_Trendline.cxx
new file mode 100644
index 0000000000..58ef6497a5
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_Trendline.cxx
@@ -0,0 +1,434 @@
+/* -*- 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 .
+ */
+
+#include "res_Trendline.hxx"
+#include <bitmaps.hlst>
+#include <chartview/ChartSfxItemIds.hxx>
+
+#include <com/sun/star/chart2/MovingAverageType.hpp>
+
+#include <svl/intitem.hxx>
+#include <svl/numformat.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/formatter.hxx>
+#include <vcl/weld.hxx>
+
+using namespace css::chart2;
+
+namespace chart
+{
+
+static void lcl_setValue(weld::FormattedSpinButton& rFmtField, double fValue )
+{
+ Formatter& rFieldFormatter = rFmtField.GetFormatter();
+ rFieldFormatter.SetValue(fValue);
+ rFieldFormatter.SetDefaultValue( fValue );
+}
+
+TrendlineResources::TrendlineResources(weld::Builder& rBuilder, const SfxItemSet& rInAttrs)
+ : m_eTrendLineType(SvxChartRegress::Linear)
+ , m_bTrendLineUnique(true)
+ , m_pNumFormatter(nullptr)
+ , m_nNbPoints(0)
+ , m_xRB_Linear(rBuilder.weld_radio_button("linear"))
+ , m_xRB_Logarithmic(rBuilder.weld_radio_button("logarithmic"))
+ , m_xRB_Exponential(rBuilder.weld_radio_button("exponential"))
+ , m_xRB_Power(rBuilder.weld_radio_button("power"))
+ , m_xRB_Polynomial(rBuilder.weld_radio_button("polynomial"))
+ , m_xRB_MovingAverage(rBuilder.weld_radio_button("movingAverage"))
+ , m_xFI_Linear(rBuilder.weld_image("imageLinear"))
+ , m_xFI_Logarithmic(rBuilder.weld_image("imageLogarithmic"))
+ , m_xFI_Exponential(rBuilder.weld_image("imageExponential"))
+ , m_xFI_Power(rBuilder.weld_image("imagePower"))
+ , m_xFI_Polynomial(rBuilder.weld_image("imagePolynomial"))
+ , m_xFI_MovingAverage(rBuilder.weld_image("imageMovingAverage"))
+ , m_xNF_Degree(rBuilder.weld_spin_button("degree"))
+ , m_xNF_Period(rBuilder.weld_spin_button("period"))
+ , m_xEE_Name(rBuilder.weld_entry("entry_name"))
+ , m_xFmtFld_ExtrapolateForward(rBuilder.weld_formatted_spin_button("extrapolateForward"))
+ , m_xFmtFld_ExtrapolateBackward(rBuilder.weld_formatted_spin_button("extrapolateBackward"))
+ , m_xCB_SetIntercept(rBuilder.weld_check_button("setIntercept"))
+ , m_xFmtFld_InterceptValue(rBuilder.weld_formatted_spin_button("interceptValue"))
+ , m_xCB_ShowEquation(rBuilder.weld_check_button("showEquation"))
+ , m_xEE_XName(rBuilder.weld_entry("entry_Xname"))
+ , m_xEE_YName(rBuilder.weld_entry("entry_Yname"))
+ , m_xCB_ShowCorrelationCoeff(rBuilder.weld_check_button("showCorrelationCoefficient"))
+ , m_xCB_RegressionMovingType(rBuilder.weld_combo_box("combo_moving_type"))
+{
+ FillValueSets();
+
+ Formatter& rForwardFormatter = m_xFmtFld_ExtrapolateForward->GetFormatter();
+ rForwardFormatter.ClearMinValue();
+ rForwardFormatter.ClearMaxValue();
+ Formatter& rBackwardFormatter = m_xFmtFld_ExtrapolateBackward->GetFormatter();
+ rBackwardFormatter.ClearMinValue();
+ rBackwardFormatter.ClearMaxValue();
+ Formatter& rInterceptFormatter = m_xFmtFld_InterceptValue->GetFormatter();
+ rInterceptFormatter.ClearMinValue();
+ rInterceptFormatter.ClearMaxValue();
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, TrendlineResources, SelectTrendLine);
+ m_xRB_Linear->connect_toggled( aLink );
+ m_xRB_Logarithmic->connect_toggled( aLink );
+ m_xRB_Exponential->connect_toggled( aLink );
+ m_xRB_Power->connect_toggled( aLink );
+ m_xRB_Polynomial->connect_toggled( aLink );
+ m_xRB_MovingAverage->connect_toggled( aLink );
+
+ Link<weld::SpinButton&,void> aLink2 = LINK(this, TrendlineResources, ChangeSpinValue);
+ m_xNF_Degree->connect_value_changed(aLink2);
+ m_xNF_Period->connect_value_changed(aLink2);
+ m_xFmtFld_InterceptValue->connect_value_changed(LINK(this, TrendlineResources, ChangeFormattedValue));
+
+ m_xCB_ShowEquation->connect_toggled(LINK(this, TrendlineResources, ShowEquation));
+
+ Reset( rInAttrs );
+ UpdateControlStates();
+}
+
+TrendlineResources::~TrendlineResources()
+{}
+
+IMPL_LINK_NOARG(TrendlineResources, SelectTrendLine, weld::Toggleable&, void)
+{
+ if (m_xRB_Linear->get_active())
+ m_eTrendLineType = SvxChartRegress::Linear;
+ else if (m_xRB_Logarithmic->get_active())
+ m_eTrendLineType = SvxChartRegress::Log;
+ else if (m_xRB_Exponential->get_active())
+ m_eTrendLineType = SvxChartRegress::Exp;
+ else if (m_xRB_Power->get_active())
+ m_eTrendLineType = SvxChartRegress::Power;
+ else if (m_xRB_Polynomial->get_active())
+ m_eTrendLineType = SvxChartRegress::Polynomial;
+ else if (m_xRB_MovingAverage->get_active())
+ m_eTrendLineType = SvxChartRegress::MovingAverage;
+ m_bTrendLineUnique = true;
+
+ UpdateControlStates();
+}
+
+void TrendlineResources::Reset( const SfxItemSet& rInAttrs )
+{
+ if( const SfxStringItem* pCurveNameItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_CURVE_NAME ) )
+ {
+ OUString aName = pCurveNameItem->GetValue();
+ m_xEE_Name->set_text(aName);
+ }
+ else
+ {
+ m_xEE_Name->set_text("");
+ }
+ if( const SfxStringItem* pRegressionXNameItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_XNAME ) )
+ {
+ OUString aName = pRegressionXNameItem->GetValue();
+ m_xEE_XName->set_text(aName);
+ }
+ else
+ {
+ m_xEE_XName->set_text("x");
+ }
+ if( const SfxStringItem* pRegressionYNameItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_YNAME ) )
+ {
+ OUString aName = pRegressionYNameItem->GetValue();
+ m_xEE_YName->set_text(aName);
+ }
+ else
+ {
+ m_xEE_YName->set_text("f(x)");
+ }
+
+ const SfxPoolItem* pPoolItem = nullptr;
+ SfxItemState aState = rInAttrs.GetItemState( SCHATTR_REGRESSION_TYPE, true, &pPoolItem );
+ m_bTrendLineUnique = ( aState != SfxItemState::DONTCARE );
+ if( aState == SfxItemState::SET )
+ {
+ const SvxChartRegressItem * pItem = dynamic_cast< const SvxChartRegressItem * >( pPoolItem );
+ if( pItem )
+ {
+ m_eTrendLineType = pItem->GetValue();
+ }
+ }
+
+ if( const SfxInt32Item* pDegreeItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_DEGREE ) )
+ {
+ sal_Int32 nDegree = pDegreeItem->GetValue();
+ m_xNF_Degree->set_value( nDegree );
+ }
+ else
+ {
+ m_xNF_Degree->set_value( 2 );
+ }
+
+ m_xNF_Degree->save_value();
+
+ if( const SfxInt32Item* pPeriodItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_PERIOD ) )
+ {
+ sal_Int32 nPeriod = pPeriodItem->GetValue();
+ m_xNF_Period->set_value( nPeriod );
+ }
+ else
+ {
+ m_xNF_Period->set_value( 2 );
+ }
+
+ m_xNF_Period->save_value();
+
+ double nValue = 0.0;
+ if( const SvxDoubleItem* pForwardItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD ) )
+ {
+ nValue = pForwardItem->GetValue() ;
+ }
+ lcl_setValue(*m_xFmtFld_ExtrapolateForward, nValue);
+
+ nValue = 0.0;
+ if( const SvxDoubleItem* pBackwardItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD ) )
+ {
+ nValue = pBackwardItem->GetValue() ;
+ }
+ lcl_setValue(*m_xFmtFld_ExtrapolateBackward, nValue);
+
+ nValue = 0.0;
+ if( const SvxDoubleItem* pValueItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_INTERCEPT_VALUE ) )
+ {
+ nValue = pValueItem->GetValue() ;
+ }
+ lcl_setValue(*m_xFmtFld_InterceptValue, nValue);
+
+ aState = rInAttrs.GetItemState( SCHATTR_REGRESSION_SET_INTERCEPT, true, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCB_SetIntercept->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if( aState == SfxItemState::SET )
+ m_xCB_SetIntercept->set_active( static_cast< const SfxBoolItem * >( pPoolItem )->GetValue());
+ }
+
+ aState = rInAttrs.GetItemState( SCHATTR_REGRESSION_SHOW_EQUATION, true, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCB_ShowEquation->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if( aState == SfxItemState::SET )
+ m_xCB_ShowEquation->set_active( static_cast< const SfxBoolItem * >( pPoolItem )->GetValue());
+ }
+
+ aState = rInAttrs.GetItemState( SCHATTR_REGRESSION_SHOW_COEFF, true, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCB_ShowCorrelationCoeff->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ if( aState == SfxItemState::SET )
+ m_xCB_ShowCorrelationCoeff->set_active( static_cast< const SfxBoolItem * >( pPoolItem )->GetValue());
+ }
+
+ if( const SfxInt32Item* pMovingTypeItem = rInAttrs.GetItemIfSet( SCHATTR_REGRESSION_MOVING_TYPE ) )
+ {
+ sal_Int32 nMovingType = pMovingTypeItem->GetValue();
+ if (nMovingType == MovingAverageType::Prior)
+ m_xCB_RegressionMovingType->set_active(0);
+ else if (nMovingType == MovingAverageType::Central)
+ m_xCB_RegressionMovingType->set_active(1);
+ else if (nMovingType == MovingAverageType::AveragedAbscissa)
+ m_xCB_RegressionMovingType->set_active(2);
+ }
+ else
+ {
+ m_xCB_RegressionMovingType->set_active(0);
+ }
+
+ if( !m_bTrendLineUnique )
+ return;
+
+ switch( m_eTrendLineType )
+ {
+ case SvxChartRegress::Linear :
+ m_xRB_Linear->set_active(true);
+ break;
+ case SvxChartRegress::Log :
+ m_xRB_Logarithmic->set_active(true);
+ break;
+ case SvxChartRegress::Exp :
+ m_xRB_Exponential->set_active(true);
+ break;
+ case SvxChartRegress::Power :
+ m_xRB_Power->set_active(true);
+ break;
+ case SvxChartRegress::Polynomial :
+ m_xRB_Polynomial->set_active(true);
+ break;
+ case SvxChartRegress::MovingAverage :
+ m_xRB_MovingAverage->set_active(true);
+ break;
+ default:
+ break;
+ }
+}
+
+void TrendlineResources::FillItemSet(SfxItemSet* rOutAttrs) const
+{
+ if( m_bTrendLineUnique )
+ rOutAttrs->Put( SvxChartRegressItem( m_eTrendLineType, SCHATTR_REGRESSION_TYPE ));
+
+ if (m_eTrendLineType == SvxChartRegress::MovingAverage)
+ {
+ sal_Int32 nType = MovingAverageType::Prior;
+ if (m_xCB_RegressionMovingType->get_active() == 1)
+ nType = MovingAverageType::Central;
+ else if (m_xCB_RegressionMovingType->get_active() == 2)
+ nType = MovingAverageType::AveragedAbscissa;
+
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_REGRESSION_MOVING_TYPE, nType));
+ }
+
+ if( m_xCB_ShowEquation->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_REGRESSION_SHOW_EQUATION, m_xCB_ShowEquation->get_active() ));
+
+ if( m_xCB_ShowCorrelationCoeff->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_REGRESSION_SHOW_COEFF, m_xCB_ShowCorrelationCoeff->get_active() ));
+
+ OUString aName = m_xEE_Name->get_text();
+ rOutAttrs->Put(SfxStringItem(SCHATTR_REGRESSION_CURVE_NAME, aName));
+ aName = m_xEE_XName->get_text();
+ if ( aName.isEmpty() )
+ aName = "x";
+ rOutAttrs->Put(SfxStringItem(SCHATTR_REGRESSION_XNAME, aName));
+ aName = m_xEE_YName->get_text();
+ if ( aName.isEmpty() )
+ aName = "f(x)";
+ rOutAttrs->Put(SfxStringItem(SCHATTR_REGRESSION_YNAME, aName));
+
+ sal_Int32 aDegree = m_xNF_Degree->get_value();
+ rOutAttrs->Put(SfxInt32Item( SCHATTR_REGRESSION_DEGREE, aDegree ) );
+
+ sal_Int32 aPeriod = m_xNF_Period->get_value();
+ rOutAttrs->Put(SfxInt32Item( SCHATTR_REGRESSION_PERIOD, aPeriod ) );
+
+ sal_uInt32 nIndex = 0;
+ double aValue = 0.0;
+ (void)m_pNumFormatter->IsNumberFormat(m_xFmtFld_ExtrapolateForward->get_text(),nIndex,aValue);
+ rOutAttrs->Put(SvxDoubleItem( aValue, SCHATTR_REGRESSION_EXTRAPOLATE_FORWARD ) );
+
+ aValue = 0.0;
+ (void)m_pNumFormatter->IsNumberFormat(m_xFmtFld_ExtrapolateBackward->get_text(),nIndex,aValue);
+ rOutAttrs->Put(SvxDoubleItem( aValue, SCHATTR_REGRESSION_EXTRAPOLATE_BACKWARD ) );
+
+ if( m_xCB_SetIntercept->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_REGRESSION_SET_INTERCEPT, m_xCB_SetIntercept->get_active() ));
+
+ aValue = 0.0;
+ (void)m_pNumFormatter->IsNumberFormat(m_xFmtFld_InterceptValue->get_text(),nIndex,aValue);
+ rOutAttrs->Put(SvxDoubleItem( aValue, SCHATTR_REGRESSION_INTERCEPT_VALUE ) );
+}
+
+void TrendlineResources::FillValueSets()
+{
+ m_xFI_Linear->set_from_icon_name(BMP_REGRESSION_LINEAR);
+ m_xFI_Logarithmic->set_from_icon_name(BMP_REGRESSION_LOG);
+ m_xFI_Exponential->set_from_icon_name(BMP_REGRESSION_EXP);
+ m_xFI_Power->set_from_icon_name(BMP_REGRESSION_POWER);
+ m_xFI_Polynomial->set_from_icon_name(BMP_REGRESSION_POLYNOMIAL);
+ m_xFI_MovingAverage->set_from_icon_name(BMP_REGRESSION_MOVING_AVERAGE);
+}
+
+void TrendlineResources::UpdateControlStates()
+{
+ if( m_nNbPoints > 0 )
+ {
+ sal_Int32 nMaxValue = m_nNbPoints - 1 + (m_xCB_SetIntercept->get_active() ? 1 : 0);
+ m_xNF_Degree->set_max(nMaxValue);
+ m_xNF_Period->set_max(m_nNbPoints - 1);
+ }
+ bool bMovingAverage = ( m_eTrendLineType == SvxChartRegress::MovingAverage );
+ bool bPolynomial = ( m_eTrendLineType == SvxChartRegress::Polynomial );
+ bool bInterceptAvailable = ( m_eTrendLineType == SvxChartRegress::Linear )
+ || ( m_eTrendLineType == SvxChartRegress::Polynomial )
+ || ( m_eTrendLineType == SvxChartRegress::Exp );
+ m_xFmtFld_ExtrapolateForward->set_sensitive( !bMovingAverage );
+ m_xFmtFld_ExtrapolateBackward->set_sensitive( !bMovingAverage );
+ m_xCB_SetIntercept->set_sensitive( bInterceptAvailable );
+ m_xFmtFld_InterceptValue->set_sensitive( bInterceptAvailable );
+ if( bMovingAverage )
+ {
+ m_xCB_ShowCorrelationCoeff->set_state(TRISTATE_FALSE);
+ }
+ m_xCB_ShowCorrelationCoeff->set_sensitive( !bMovingAverage );
+ m_xCB_RegressionMovingType->set_sensitive(bMovingAverage);
+ m_xNF_Period->set_sensitive(bMovingAverage);
+ m_xNF_Degree->set_sensitive(bPolynomial);
+ m_xEE_XName->set_sensitive( !bMovingAverage && m_xCB_ShowEquation->get_active() );
+ m_xEE_YName->set_sensitive( !bMovingAverage && m_xCB_ShowEquation->get_active() );
+}
+
+IMPL_LINK(TrendlineResources, ChangeSpinValue, weld::SpinButton&, rNumericField, void)
+{
+ if (&rNumericField == m_xNF_Degree.get())
+ {
+ if (!m_xRB_Polynomial->get_active() && m_xNF_Degree->get_value_changed_from_saved())
+ {
+ m_xRB_Polynomial->set_active(true);
+ SelectTrendLine(*m_xRB_Polynomial);
+ }
+ }
+ else if (&rNumericField == m_xNF_Period.get())
+ {
+ if (!m_xRB_MovingAverage->get_active() && m_xNF_Period->get_value_changed_from_saved())
+ {
+ m_xRB_MovingAverage->set_active(true);
+ SelectTrendLine(*m_xRB_MovingAverage);
+ }
+ }
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(TrendlineResources, ChangeFormattedValue, weld::FormattedSpinButton&, void)
+{
+ if (!m_xCB_SetIntercept->get_active())
+ m_xCB_SetIntercept->set_active(true);
+ UpdateControlStates();
+}
+
+void TrendlineResources::SetNumFormatter( SvNumberFormatter* pFormatter )
+{
+ m_pNumFormatter = pFormatter;
+ m_xFmtFld_ExtrapolateForward->GetFormatter().SetFormatter(m_pNumFormatter);
+ m_xFmtFld_ExtrapolateBackward->GetFormatter().SetFormatter(m_pNumFormatter);
+ m_xFmtFld_InterceptValue->GetFormatter().SetFormatter(m_pNumFormatter);
+}
+
+void TrendlineResources::SetNbPoints( sal_Int32 nNbPoints )
+{
+ m_nNbPoints = nNbPoints;
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(TrendlineResources, ShowEquation, weld::Toggleable&, void)
+{
+ UpdateControlStates();
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/res_Trendline.hxx b/chart2/source/controller/dialogs/res_Trendline.hxx
new file mode 100644
index 0000000000..e520d6da3b
--- /dev/null
+++ b/chart2/source/controller/dialogs/res_Trendline.hxx
@@ -0,0 +1,98 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <tools/link.hxx>
+#include <svl/itemset.hxx>
+#include <svx/chrtitem.hxx>
+
+namespace weld { class Builder; }
+namespace weld { class CheckButton; }
+namespace weld { class ComboBox; }
+namespace weld { class Entry; }
+namespace weld { class FormattedSpinButton; }
+namespace weld { class Image; }
+namespace weld { class RadioButton; }
+namespace weld { class SpinButton; }
+namespace weld { class Toggleable; }
+
+class SvNumberFormatter;
+
+namespace chart
+{
+
+class TrendlineResources final
+{
+public:
+ TrendlineResources(weld::Builder& rParent, const SfxItemSet& rInAttrs);
+ ~TrendlineResources();
+
+ void Reset(const SfxItemSet& rInAttrs);
+ void FillItemSet(SfxItemSet* rOutAttrs) const;
+
+ void FillValueSets();
+
+ void SetNumFormatter( SvNumberFormatter* pFormatter );
+ void SetNbPoints( sal_Int32 nNbPoints );
+
+private:
+ SvxChartRegress m_eTrendLineType;
+
+ bool m_bTrendLineUnique;
+
+ SvNumberFormatter* m_pNumFormatter;
+ sal_Int32 m_nNbPoints;
+
+ std::unique_ptr<weld::RadioButton> m_xRB_Linear;
+ std::unique_ptr<weld::RadioButton> m_xRB_Logarithmic;
+ std::unique_ptr<weld::RadioButton> m_xRB_Exponential;
+ std::unique_ptr<weld::RadioButton> m_xRB_Power;
+ std::unique_ptr<weld::RadioButton> m_xRB_Polynomial;
+ std::unique_ptr<weld::RadioButton> m_xRB_MovingAverage;
+
+ std::unique_ptr<weld::Image> m_xFI_Linear;
+ std::unique_ptr<weld::Image> m_xFI_Logarithmic;
+ std::unique_ptr<weld::Image> m_xFI_Exponential;
+ std::unique_ptr<weld::Image> m_xFI_Power;
+ std::unique_ptr<weld::Image> m_xFI_Polynomial;
+ std::unique_ptr<weld::Image> m_xFI_MovingAverage;
+
+ std::unique_ptr<weld::SpinButton> m_xNF_Degree;
+ std::unique_ptr<weld::SpinButton> m_xNF_Period;
+ std::unique_ptr<weld::Entry> m_xEE_Name;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFld_ExtrapolateForward;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFld_ExtrapolateBackward;
+ std::unique_ptr<weld::CheckButton> m_xCB_SetIntercept;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFld_InterceptValue;
+ std::unique_ptr<weld::CheckButton> m_xCB_ShowEquation;
+ std::unique_ptr<weld::Entry> m_xEE_XName;
+ std::unique_ptr<weld::Entry> m_xEE_YName;
+ std::unique_ptr<weld::CheckButton> m_xCB_ShowCorrelationCoeff;
+ std::unique_ptr<weld::ComboBox> m_xCB_RegressionMovingType;
+
+ void UpdateControlStates();
+ DECL_LINK(SelectTrendLine, weld::Toggleable&, void);
+ DECL_LINK(ChangeSpinValue, weld::SpinButton&, void);
+ DECL_LINK(ChangeFormattedValue, weld::FormattedSpinButton&, void);
+ DECL_LINK(ShowEquation, weld::Toggleable&, void);
+};
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneAppearance.cxx b/chart2/source/controller/dialogs/tp_3D_SceneAppearance.cxx
new file mode 100644
index 0000000000..e07969c957
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneAppearance.cxx
@@ -0,0 +1,318 @@
+/* -*- 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 .
+ */
+
+#include "tp_3D_SceneAppearance.hxx"
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <ThreeDHelper.hxx>
+#include <ControllerLockGuard.hxx>
+#include <Diagram.hxx>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+struct lcl_ModelProperties
+{
+ drawing::ShadeMode m_aShadeMode;
+ sal_Int32 m_nRoundedEdges;
+ sal_Int32 m_nObjectLines;
+ ::chart::ThreeDLookScheme m_eScheme;
+
+ lcl_ModelProperties()
+ : m_aShadeMode(drawing::ShadeMode_FLAT)
+ , m_nRoundedEdges(-1)
+ , m_nObjectLines(-1)
+ , m_eScheme(::chart::ThreeDLookScheme::ThreeDLookScheme_Unknown)
+ {}
+};
+
+lcl_ModelProperties lcl_getPropertiesFromModel( rtl::Reference<::chart::ChartModel> const & xModel )
+{
+ lcl_ModelProperties aProps;
+ try
+ {
+ rtl::Reference< ::chart::Diagram > xDiagram( xModel->getFirstChartDiagram() );
+ xDiagram->getPropertyValue( "D3DSceneShadeMode" ) >>= aProps.m_aShadeMode;
+ ::chart::ThreeDHelper::getRoundedEdgesAndObjectLines( xDiagram, aProps.m_nRoundedEdges, aProps.m_nObjectLines );
+ aProps.m_eScheme = xDiagram->detectScheme();
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return aProps;
+}
+
+void lcl_setShadeModeAtModel( rtl::Reference<::chart::ChartModel> const & xModel, drawing::ShadeMode aShadeMode )
+{
+ try
+ {
+ rtl::Reference< ::chart::Diagram > xDiaProp = xModel->getFirstChartDiagram();
+ xDiaProp->setPropertyValue( "D3DSceneShadeMode" , uno::Any( aShadeMode ));
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+#define POS_3DSCHEME_SIMPLE 0
+#define POS_3DSCHEME_REALISTIC 1
+#define POS_3DSCHEME_CUSTOM 2
+
+ThreeD_SceneAppearance_TabPage::ThreeD_SceneAppearance_TabPage(weld::Container* pParent,
+ rtl::Reference<::chart::ChartModel> xChartModel,
+ ControllerLockHelper& rControllerLockHelper)
+ : m_xChartModel(std::move(xChartModel))
+ , m_bUpdateOtherControls(true)
+ , m_bCommitToModel(true)
+ , m_rControllerLockHelper(rControllerLockHelper)
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/schart/ui/tp_3D_SceneAppearance.ui"))
+ , m_xContainer(m_xBuilder->weld_container("tp_3D_SceneAppearance"))
+ , m_xLB_Scheme(m_xBuilder->weld_combo_box("LB_SCHEME"))
+ , m_xCB_Shading(m_xBuilder->weld_check_button("CB_SHADING"))
+ , m_xCB_ObjectLines(m_xBuilder->weld_check_button("CB_OBJECTLINES"))
+ , m_xCB_RoundedEdge(m_xBuilder->weld_check_button("CB_ROUNDEDEDGE"))
+{
+ m_aCustom = m_xLB_Scheme->get_text(POS_3DSCHEME_CUSTOM);
+ m_xLB_Scheme->remove(POS_3DSCHEME_CUSTOM);
+
+ m_xLB_Scheme->connect_changed( LINK( this, ThreeD_SceneAppearance_TabPage, SelectSchemeHdl ) );
+
+ m_xCB_RoundedEdge->connect_toggled( LINK( this, ThreeD_SceneAppearance_TabPage, SelectRoundedEdgeOrObjectLines ) );
+ m_xCB_Shading->connect_toggled( LINK( this, ThreeD_SceneAppearance_TabPage, SelectShading ) );
+ m_xCB_ObjectLines->connect_toggled( LINK( this, ThreeD_SceneAppearance_TabPage, SelectRoundedEdgeOrObjectLines ) );
+
+ initControlsFromModel();
+}
+
+ThreeD_SceneAppearance_TabPage::~ThreeD_SceneAppearance_TabPage()
+{
+}
+
+void ThreeD_SceneAppearance_TabPage::ActivatePage()
+{
+ updateScheme();
+}
+
+void ThreeD_SceneAppearance_TabPage::applyRoundedEdgeAndObjectLinesToModel()
+{
+ if(!m_bCommitToModel)
+ return;
+
+ sal_Int32 nObjectLines = -1;
+
+ switch( m_xCB_ObjectLines->get_state())
+ {
+ case TRISTATE_FALSE:
+ nObjectLines = 0;
+ break;
+ case TRISTATE_TRUE:
+ nObjectLines = 1;
+ break;
+ case TRISTATE_INDET:
+ nObjectLines = -1;
+ break;
+ }
+
+ sal_Int32 nCurrentRoundedEdges = -1;
+ switch( m_xCB_RoundedEdge->get_state() )
+ {
+ case TRISTATE_FALSE:
+ nCurrentRoundedEdges = 0;
+ break;
+ case TRISTATE_TRUE:
+ nCurrentRoundedEdges = 5;
+ break;
+ case TRISTATE_INDET:
+ nCurrentRoundedEdges = -1;
+ break;
+ }
+
+ // locked controllers
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+ ThreeDHelper::setRoundedEdgesAndObjectLines(
+ m_xChartModel->getFirstChartDiagram(), nCurrentRoundedEdges, nObjectLines );
+}
+
+void ThreeD_SceneAppearance_TabPage::applyShadeModeToModel()
+{
+ if(!m_bCommitToModel)
+ return;
+
+ drawing::ShadeMode aShadeMode = drawing::ShadeMode_PHONG;
+
+ switch( m_xCB_Shading->get_state())
+ {
+ case TRISTATE_FALSE:
+ aShadeMode = drawing::ShadeMode_FLAT;
+ break;
+ case TRISTATE_TRUE:
+ aShadeMode = drawing::ShadeMode_SMOOTH;
+ break;
+ case TRISTATE_INDET:
+ // nothing
+ break;
+ }
+
+ lcl_setShadeModeAtModel( m_xChartModel, aShadeMode );
+}
+
+void ThreeD_SceneAppearance_TabPage::initControlsFromModel()
+{
+ m_bCommitToModel = false;
+ m_bUpdateOtherControls = false;
+
+ lcl_ModelProperties aProps( lcl_getPropertiesFromModel( m_xChartModel ));
+
+ if(aProps.m_aShadeMode == drawing::ShadeMode_FLAT)
+ {
+ m_xCB_Shading->set_active(false);
+ }
+ else if(aProps.m_aShadeMode == drawing::ShadeMode_SMOOTH)
+ {
+ m_xCB_Shading->set_active(true);
+ }
+ else
+ {
+ m_xCB_Shading->set_state(TRISTATE_INDET);
+ }
+
+ if(aProps.m_nObjectLines == 0)
+ {
+ m_xCB_ObjectLines->set_active(false);
+ }
+ else if(aProps.m_nObjectLines==1)
+ {
+ m_xCB_ObjectLines->set_active(true);
+ }
+ else
+ {
+ m_xCB_ObjectLines->set_state(TRISTATE_INDET);
+ }
+
+ if(aProps.m_nRoundedEdges >= 5)
+ {
+ m_xCB_RoundedEdge->set_active(true);
+ }
+ else if(aProps.m_nRoundedEdges<0)
+ {
+ m_xCB_RoundedEdge->set_state(TRISTATE_INDET);
+ }
+ else
+ {
+ m_xCB_RoundedEdge->set_active(false);
+ }
+ m_xCB_RoundedEdge->set_sensitive( !m_xCB_ObjectLines->get_active() );
+
+ updateScheme();
+
+ m_bCommitToModel = true;
+ m_bUpdateOtherControls = true;
+}
+
+void ThreeD_SceneAppearance_TabPage::updateScheme()
+{
+ lcl_ModelProperties aProps( lcl_getPropertiesFromModel( m_xChartModel ));
+
+ if (m_xLB_Scheme->get_count() == (POS_3DSCHEME_CUSTOM+1))
+ m_xLB_Scheme->remove(POS_3DSCHEME_CUSTOM);
+ switch( aProps.m_eScheme )
+ {
+ case ThreeDLookScheme::ThreeDLookScheme_Simple:
+ m_xLB_Scheme->set_active( POS_3DSCHEME_SIMPLE );
+ break;
+ case ThreeDLookScheme::ThreeDLookScheme_Realistic:
+ m_xLB_Scheme->set_active( POS_3DSCHEME_REALISTIC );
+ break;
+ case ThreeDLookScheme::ThreeDLookScheme_Unknown:
+ {
+ m_xLB_Scheme->insert_text(POS_3DSCHEME_CUSTOM, m_aCustom);
+ m_xLB_Scheme->set_active(POS_3DSCHEME_CUSTOM);
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneAppearance_TabPage, SelectSchemeHdl, weld::ComboBox&, void)
+{
+ if( !m_bUpdateOtherControls )
+ return;
+
+ {
+ // locked controllers
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+
+ rtl::Reference< Diagram > xDiagram = m_xChartModel->getFirstChartDiagram();
+
+ if( m_xLB_Scheme->get_active() == POS_3DSCHEME_REALISTIC )
+ xDiagram->setScheme( ThreeDLookScheme::ThreeDLookScheme_Realistic );
+ else if( m_xLB_Scheme->get_active() == POS_3DSCHEME_SIMPLE )
+ xDiagram->setScheme( ThreeDLookScheme::ThreeDLookScheme_Simple );
+ else
+ {
+ OSL_FAIL( "Invalid Entry selected" );
+ }
+ }
+
+ // update other controls
+ initControlsFromModel();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneAppearance_TabPage, SelectShading, weld::Toggleable&, void)
+{
+ if( !m_bUpdateOtherControls )
+ return;
+
+ applyShadeModeToModel();
+ updateScheme();
+}
+
+IMPL_LINK(ThreeD_SceneAppearance_TabPage, SelectRoundedEdgeOrObjectLines, weld::Toggleable&, rCheckBox, void)
+{
+ if( !m_bUpdateOtherControls )
+ return;
+
+ if (&rCheckBox == m_xCB_ObjectLines.get())
+ {
+ m_bUpdateOtherControls = false;
+ m_xCB_RoundedEdge->set_sensitive( !m_xCB_ObjectLines->get_active() );
+ if(!m_xCB_RoundedEdge->get_sensitive())
+ m_xCB_RoundedEdge->set_active(false);
+ m_bUpdateOtherControls = true;
+ }
+
+ applyRoundedEdgeAndObjectLinesToModel();
+ updateScheme();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneAppearance.hxx b/chart2/source/controller/dialogs/tp_3D_SceneAppearance.hxx
new file mode 100644
index 0000000000..4136625172
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneAppearance.hxx
@@ -0,0 +1,69 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+namespace chart { class ControllerLockHelper; }
+namespace com::sun::star::frame { class XModel; }
+
+namespace chart
+{
+class ChartModel;
+
+class ThreeD_SceneAppearance_TabPage
+{
+public:
+ ThreeD_SceneAppearance_TabPage(
+ weld::Container* pParent,
+ rtl::Reference<::chart::ChartModel> xChartModel,
+ ControllerLockHelper & rControllerLockHelper );
+ void ActivatePage();
+ ~ThreeD_SceneAppearance_TabPage();
+
+private:
+ DECL_LINK( SelectSchemeHdl, weld::ComboBox&, void );
+ DECL_LINK( SelectShading, weld::Toggleable&, void );
+ DECL_LINK( SelectRoundedEdgeOrObjectLines, weld::Toggleable&, void );
+
+ void initControlsFromModel();
+ void applyShadeModeToModel();
+ void applyRoundedEdgeAndObjectLinesToModel();
+ void updateScheme();
+
+private:
+ rtl::Reference<::chart::ChartModel> m_xChartModel;
+
+ bool m_bUpdateOtherControls;
+ bool m_bCommitToModel;
+ OUString m_aCustom;
+
+ ControllerLockHelper& m_rControllerLockHelper;
+
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ std::unique_ptr<weld::ComboBox> m_xLB_Scheme;
+ std::unique_ptr<weld::CheckButton> m_xCB_Shading;
+ std::unique_ptr<weld::CheckButton> m_xCB_ObjectLines;
+ std::unique_ptr<weld::CheckButton> m_xCB_RoundedEdge;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneGeometry.cxx b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.cxx
new file mode 100644
index 0000000000..138952775e
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.cxx
@@ -0,0 +1,258 @@
+/* -*- 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 .
+ */
+
+#include "tp_3D_SceneGeometry.hxx"
+
+#include <Diagram.hxx>
+#include <DiagramHelper.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeHelper.hxx>
+#include <ThreeDHelper.hxx>
+#include <ControllerLockGuard.hxx>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <comphelper/diagnose_ex.hxx>
+#include <tools/helpers.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+namespace chart
+{
+
+using namespace ::com::sun::star;
+
+namespace
+{
+
+void lcl_SetMetricFieldLimits(weld::MetricSpinButton& rField, sal_Int64 nLimit)
+{
+ rField.set_range(-1*nLimit, nLimit, FieldUnit::DEGREE);
+}
+
+}
+
+ThreeD_SceneGeometry_TabPage::ThreeD_SceneGeometry_TabPage(weld::Container* pParent,
+ rtl::Reference< ::chart::Diagram > xDiagram,
+ ControllerLockHelper & rControllerLockHelper)
+ : m_xDiagram(std::move( xDiagram ))
+ , m_aAngleTimer("chart2 ThreeD_SceneGeometry_TabPage m_aAngleTimer")
+ , m_aPerspectiveTimer("chart2 ThreeD_SceneGeometry_TabPage m_aPerspectiveTimer")
+ , m_nXRotation(0)
+ , m_nYRotation(0)
+ , m_nZRotation(0)
+ , m_bAngleChangePending( false )
+ , m_bPerspectiveChangePending( false )
+ , m_rControllerLockHelper( rControllerLockHelper )
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/schart/ui/tp_3D_SceneGeometry.ui"))
+ , m_xContainer(m_xBuilder->weld_container("tp_3DSceneGeometry"))
+ , m_xCbxRightAngledAxes(m_xBuilder->weld_check_button("CBX_RIGHT_ANGLED_AXES"))
+ , m_xMFXRotation(m_xBuilder->weld_metric_spin_button("MTR_FLD_X_ROTATION", FieldUnit::DEGREE))
+ , m_xMFYRotation(m_xBuilder->weld_metric_spin_button("MTR_FLD_Y_ROTATION", FieldUnit::DEGREE))
+ , m_xFtZRotation(m_xBuilder->weld_label("FT_Z_ROTATION"))
+ , m_xMFZRotation(m_xBuilder->weld_metric_spin_button("MTR_FLD_Z_ROTATION", FieldUnit::DEGREE))
+ , m_xCbxPerspective(m_xBuilder->weld_check_button("CBX_PERSPECTIVE"))
+ , m_xMFPerspective(m_xBuilder->weld_metric_spin_button("MTR_FLD_PERSPECTIVE", FieldUnit::PERCENT))
+{
+ double fXAngle, fYAngle, fZAngle;
+ m_xDiagram->getRotationAngle( fXAngle, fYAngle, fZAngle );
+
+ fXAngle = basegfx::rad2deg(fXAngle);
+ fYAngle = basegfx::rad2deg(fYAngle);
+ fZAngle = basegfx::rad2deg(fZAngle);
+
+ OSL_ENSURE( fZAngle>=-90 && fZAngle<=90, "z angle is out of valid range" );
+
+ lcl_SetMetricFieldLimits( *m_xMFZRotation, 90 );
+
+ m_nXRotation = NormAngle180(
+ ::basegfx::fround(fXAngle * pow(10.0, m_xMFXRotation->get_digits())));
+ m_nYRotation = NormAngle180(
+ ::basegfx::fround(-1.0 * fYAngle * pow(10.0, m_xMFYRotation->get_digits())));
+ m_nZRotation = NormAngle180(
+ ::basegfx::fround(-1.0 * fZAngle * pow(10.0, m_xMFZRotation->get_digits())));
+
+ m_xMFXRotation->set_value(m_nXRotation, FieldUnit::DEGREE);
+ m_xMFYRotation->set_value(m_nYRotation, FieldUnit::DEGREE);
+ m_xMFZRotation->set_value(m_nZRotation, FieldUnit::DEGREE);
+
+ const int nTimeout = 4*EDIT_UPDATEDATA_TIMEOUT;
+ m_aAngleTimer.SetTimeout(nTimeout);
+ m_aAngleTimer.SetInvokeHandler( LINK( this, ThreeD_SceneGeometry_TabPage, AngleChanged ) );
+
+ Link<weld::MetricSpinButton&,void> aAngleEditedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleEdited ));
+ m_xMFXRotation->connect_value_changed( aAngleEditedLink );
+ m_xMFYRotation->connect_value_changed( aAngleEditedLink );
+ m_xMFZRotation->connect_value_changed( aAngleEditedLink );
+
+ drawing::ProjectionMode aProjectionMode = drawing::ProjectionMode_PERSPECTIVE;
+ m_xDiagram->getPropertyValue( "D3DScenePerspective" ) >>= aProjectionMode;
+ m_xCbxPerspective->set_active( aProjectionMode == drawing::ProjectionMode_PERSPECTIVE );
+ m_xCbxPerspective->connect_toggled( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveToggled ));
+
+ sal_Int32 nPerspectivePercentage = 20;
+ m_xDiagram->getPropertyValue( "Perspective" ) >>= nPerspectivePercentage;
+ m_xMFPerspective->set_value(nPerspectivePercentage, FieldUnit::PERCENT);
+
+ m_aPerspectiveTimer.SetTimeout(nTimeout);
+ m_aPerspectiveTimer.SetInvokeHandler( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveChanged ) );
+ m_xMFPerspective->connect_value_changed( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveEdited ) );
+ m_xMFPerspective->set_sensitive( m_xCbxPerspective->get_active() );
+
+ //RightAngledAxes
+ if (ChartTypeHelper::isSupportingRightAngledAxes(m_xDiagram->getChartTypeByIndex(0)))
+ {
+ bool bRightAngledAxes = false;
+ m_xDiagram->getPropertyValue( "RightAngledAxes" ) >>= bRightAngledAxes;
+ m_xCbxRightAngledAxes->connect_toggled( LINK( this, ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled ));
+ m_xCbxRightAngledAxes->set_active( bRightAngledAxes );
+ RightAngledAxesToggled(*m_xCbxRightAngledAxes);
+ }
+ else
+ {
+ m_xCbxRightAngledAxes->set_sensitive(false);
+ }
+}
+
+ThreeD_SceneGeometry_TabPage::~ThreeD_SceneGeometry_TabPage()
+{
+}
+
+void ThreeD_SceneGeometry_TabPage::commitPendingChanges()
+{
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+
+ if( m_bAngleChangePending )
+ applyAnglesToModel();
+ if( m_bPerspectiveChangePending )
+ applyPerspectiveToModel();
+}
+
+void ThreeD_SceneGeometry_TabPage::applyAnglesToModel()
+{
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+
+ double fXAngle = 0.0, fYAngle = 0.0, fZAngle = 0.0;
+
+ if (m_xMFZRotation->get_sensitive())
+ m_nZRotation = m_xMFZRotation->get_value(FieldUnit::DEGREE);
+
+ fXAngle = double(m_nXRotation)/pow(10.0,m_xMFXRotation->get_digits());
+ fYAngle = double(-1.0*m_nYRotation)/pow(10.0,m_xMFYRotation->get_digits());
+ fZAngle = double(-1.0*m_nZRotation)/pow(10.0,m_xMFZRotation->get_digits());
+
+ fXAngle = basegfx::deg2rad(fXAngle);
+ fYAngle = basegfx::deg2rad(fYAngle);
+ fZAngle = basegfx::deg2rad(fZAngle);
+
+ m_xDiagram->setRotationAngle( fXAngle, fYAngle, fZAngle );
+
+ m_bAngleChangePending = false;
+ m_aAngleTimer.Stop();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, AngleEdited, weld::MetricSpinButton&, void)
+{
+ m_nXRotation = m_xMFXRotation->get_value(FieldUnit::DEGREE);
+ m_nYRotation = m_xMFYRotation->get_value(FieldUnit::DEGREE);
+
+ m_bAngleChangePending = true;
+
+ m_aAngleTimer.Start();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, AngleChanged, Timer *, void)
+{
+ applyAnglesToModel();
+}
+
+void ThreeD_SceneGeometry_TabPage::applyPerspectiveToModel()
+{
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+
+ drawing::ProjectionMode aMode = m_xCbxPerspective->get_active()
+ ? drawing::ProjectionMode_PERSPECTIVE
+ : drawing::ProjectionMode_PARALLEL;
+
+ try
+ {
+ m_xDiagram->setPropertyValue( "D3DScenePerspective" , uno::Any( aMode ));
+ m_xDiagram->setPropertyValue( "Perspective" , uno::Any( static_cast<sal_Int32>(m_xMFPerspective->get_value(FieldUnit::PERCENT)) ));
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ m_bPerspectiveChangePending = false;
+ m_aPerspectiveTimer.Stop();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, PerspectiveEdited, weld::MetricSpinButton&, void)
+{
+ m_bPerspectiveChangePending = true;
+ m_aPerspectiveTimer.Start();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, PerspectiveChanged, Timer *, void)
+{
+ applyPerspectiveToModel();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, PerspectiveToggled, weld::Toggleable&, void)
+{
+ m_xMFPerspective->set_sensitive(m_xCbxPerspective->get_active());
+ applyPerspectiveToModel();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled, weld::Toggleable&, void)
+{
+ ControllerLockHelperGuard aGuard( m_rControllerLockHelper );
+
+ bool bEnableZ = !m_xCbxRightAngledAxes->get_active();
+ m_xFtZRotation->set_sensitive( bEnableZ );
+ m_xMFZRotation->set_sensitive( bEnableZ );
+ if (!bEnableZ)
+ {
+ m_nXRotation = m_xMFXRotation->get_value(FieldUnit::DEGREE);
+ m_nYRotation = m_xMFYRotation->get_value(FieldUnit::DEGREE);
+ m_nZRotation = m_xMFZRotation->get_value(FieldUnit::DEGREE);
+
+ m_xMFXRotation->set_value(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nXRotation), ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes())), FieldUnit::DEGREE);
+ m_xMFYRotation->set_value(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nYRotation), ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes())), FieldUnit::DEGREE);
+ m_xMFZRotation->set_text("");
+
+ lcl_SetMetricFieldLimits( *m_xMFXRotation, static_cast<sal_Int64>(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()));
+ lcl_SetMetricFieldLimits( *m_xMFYRotation, static_cast<sal_Int64>(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()));
+ }
+ else
+ {
+ lcl_SetMetricFieldLimits( *m_xMFXRotation, 180 );
+ lcl_SetMetricFieldLimits( *m_xMFYRotation, 180 );
+
+ m_xMFXRotation->set_value(m_nXRotation, FieldUnit::DEGREE);
+ m_xMFYRotation->set_value(m_nYRotation, FieldUnit::DEGREE);
+ m_xMFZRotation->set_value(m_nZRotation, FieldUnit::DEGREE);
+ }
+
+ if (m_xDiagram)
+ m_xDiagram->switchRightAngledAxes( m_xCbxRightAngledAxes->get_active() );
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx
new file mode 100644
index 0000000000..d0fc8a69d6
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneGeometry.hxx
@@ -0,0 +1,87 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+#include <rtl/ref.hxx>
+
+namespace com::sun::star::beans { class XPropertySet; }
+namespace chart { class ControllerLockHelper; }
+
+namespace chart
+{
+class Diagram;
+
+class ThreeD_SceneGeometry_TabPage
+{
+public:
+ ThreeD_SceneGeometry_TabPage(weld::Container* pWindow,
+ rtl::Reference< ::chart::Diagram > xDiagram,
+ ControllerLockHelper & rControllerLockHelper);
+ ~ThreeD_SceneGeometry_TabPage();
+
+ // has to be called in case the dialog was closed with OK
+ void commitPendingChanges();
+
+ // is called by timer to apply changes to model
+ DECL_LINK( AngleChanged, Timer *, void);
+ // is called immediately when a field changes
+ DECL_LINK( AngleEdited, weld::MetricSpinButton&, void );
+
+ // is called by timer to apply changes to model
+ DECL_LINK( PerspectiveChanged, Timer *, void);
+ // is called immediately when a field changes
+ DECL_LINK( PerspectiveEdited, weld::MetricSpinButton&, void );
+ DECL_LINK( PerspectiveToggled, weld::Toggleable&, void );
+ DECL_LINK( RightAngledAxesToggled, weld::Toggleable&, void );
+
+private:
+ void applyAnglesToModel();
+ void applyPerspectiveToModel();
+
+ rtl::Reference< ::chart::Diagram > m_xDiagram;
+
+ Timer m_aAngleTimer;
+ Timer m_aPerspectiveTimer;
+
+ //to keep old values when switching to right angled axes
+ sal_Int64 m_nXRotation;
+ sal_Int64 m_nYRotation;
+ sal_Int64 m_nZRotation;
+
+ bool m_bAngleChangePending;
+ bool m_bPerspectiveChangePending;
+
+ ControllerLockHelper & m_rControllerLockHelper;
+
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ std::unique_ptr<weld::CheckButton> m_xCbxRightAngledAxes;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFXRotation;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFYRotation;
+ std::unique_ptr<weld::Label> m_xFtZRotation;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFZRotation;
+ std::unique_ptr<weld::CheckButton> m_xCbxPerspective;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFPerspective;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneIllumination.cxx b/chart2/source/controller/dialogs/tp_3D_SceneIllumination.cxx
new file mode 100644
index 0000000000..2020365fd1
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneIllumination.cxx
@@ -0,0 +1,533 @@
+/* -*- 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 .
+ */
+
+#include "tp_3D_SceneIllumination.hxx"
+#include <CommonConverters.hxx>
+#include <ControllerLockGuard.hxx>
+#include <ChartModel.hxx>
+
+#include <svx/colorbox.hxx>
+#include <svx/float3d.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svtools/colrdlg.hxx>
+#include <svx/svx3ditems.hxx>
+#include <svx/svddef.hxx>
+#include <utility>
+#include <svx/obj3d.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+namespace chart
+{
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+namespace {
+
+struct LightSource
+{
+ Color nDiffuseColor;
+ css::drawing::Direction3D aDirection;
+ bool bIsEnabled;
+
+ LightSource() :
+ nDiffuseColor( 0xcccccc ),
+ aDirection( 1.0, 1.0, -1.0 ),
+ bIsEnabled( false )
+ {}
+};
+
+}
+
+struct LightSourceInfo
+{
+ LightButton* pButton;
+ LightSource aLightSource;
+
+ LightSourceInfo();
+ void initButtonFromSource();
+};
+
+LightSourceInfo::LightSourceInfo()
+ : pButton(nullptr)
+{
+ aLightSource.nDiffuseColor = Color(0xffffff); // white
+ aLightSource.aDirection = drawing::Direction3D(1,1,1);
+ aLightSource.bIsEnabled = false;
+}
+
+void LightSourceInfo::initButtonFromSource()
+{
+ if (!pButton)
+ return;
+ pButton->switchLightOn(aLightSource.bIsEnabled);
+}
+
+namespace
+{
+ OUString lcl_makeColorName(const Color& rColor)
+ {
+ OUString aStr = SvxResId(RID_SVXFLOAT3D_FIX_R) +
+ OUString::number(rColor.GetRed()) +
+ " " +
+ SvxResId(RID_SVXFLOAT3D_FIX_G) +
+ OUString::number(rColor.GetGreen()) +
+ " " +
+ SvxResId(RID_SVXFLOAT3D_FIX_B) +
+ OUString::number(rColor.GetBlue());
+ return aStr;
+ }
+
+ void lcl_selectColor(ColorListBox& rListBox, const Color& rColor)
+ {
+ rListBox.SetNoSelection();
+ rListBox.SelectEntry({rColor, lcl_makeColorName(rColor)});
+ }
+
+ ::chart::LightSource lcl_getLightSourceFromProperties(
+ const uno::Reference< beans::XPropertySet > & xSceneProperties,
+ sal_Int32 nIndex )
+ {
+ ::chart::LightSource aResult;
+ if( 0 <= nIndex && nIndex < 8 )
+ {
+ OUString aIndex( OUString::number( nIndex + 1 ));
+
+ try
+ {
+ xSceneProperties->getPropertyValue( "D3DSceneLightColor" + aIndex ) >>= aResult.nDiffuseColor;
+ xSceneProperties->getPropertyValue( "D3DSceneLightDirection" + aIndex ) >>= aResult.aDirection;
+ xSceneProperties->getPropertyValue( "D3DSceneLightOn" + aIndex ) >>= aResult.bIsEnabled;
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ return aResult;
+ }
+
+ void lcl_setLightSource(
+ const uno::Reference< beans::XPropertySet > & xSceneProperties,
+ const ::chart::LightSource & rLightSource,
+ sal_Int32 nIndex )
+ {
+ if( 0 > nIndex || nIndex >= 8 )
+ return;
+
+ OUString aIndex( OUString::number( nIndex + 1 ));
+
+ try
+ {
+ xSceneProperties->setPropertyValue( "D3DSceneLightColor" + aIndex,
+ uno::Any( rLightSource.nDiffuseColor ));
+ xSceneProperties->setPropertyValue( "D3DSceneLightDirection" + aIndex,
+ uno::Any( rLightSource.aDirection ));
+ xSceneProperties->setPropertyValue( "D3DSceneLightOn" + aIndex,
+ uno::Any( rLightSource.bIsEnabled ));
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+
+ Color lcl_getAmbientColor(
+ const uno::Reference< beans::XPropertySet > & xSceneProperties )
+ {
+ Color nResult;
+ try
+ {
+ xSceneProperties->getPropertyValue("D3DSceneAmbientColor") >>= nResult;
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ return nResult;
+ }
+
+ void lcl_setAmbientColor(
+ const uno::Reference< beans::XPropertySet > & xSceneProperties,
+ const Color & rColor )
+ {
+ try
+ {
+ xSceneProperties->setPropertyValue("D3DSceneAmbientColor",
+ uno::Any( rColor ));
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+}
+
+ThreeD_SceneIllumination_TabPage::ThreeD_SceneIllumination_TabPage(weld::Container* pParent,
+ weld::Window* pTopLevel,
+ uno::Reference< beans::XPropertySet > xSceneProperties,
+ const rtl::Reference<::chart::ChartModel>& xChartModel)
+ : m_xSceneProperties(std::move( xSceneProperties ))
+ , m_aTimerTriggeredControllerLock( xChartModel )
+ , m_bInCommitToModel( false )
+ , m_aModelChangeListener( LINK( this, ThreeD_SceneIllumination_TabPage, fillControlsFromModel ) )
+ , m_xChartModel( xChartModel )
+ , m_pTopLevel(pTopLevel)
+ , m_xBuilder(Application::CreateBuilder(pParent, "modules/schart/ui/tp_3D_SceneIllumination.ui"))
+ , m_xContainer(m_xBuilder->weld_container("tp_3D_SceneIllumination"))
+ , m_aBtn_Light1(m_xBuilder->weld_toggle_button("BTN_LIGHT_1"))
+ , m_aBtn_Light2(m_xBuilder->weld_toggle_button("BTN_LIGHT_2"))
+ , m_aBtn_Light3(m_xBuilder->weld_toggle_button("BTN_LIGHT_3"))
+ , m_aBtn_Light4(m_xBuilder->weld_toggle_button("BTN_LIGHT_4"))
+ , m_aBtn_Light5(m_xBuilder->weld_toggle_button("BTN_LIGHT_5"))
+ , m_aBtn_Light6(m_xBuilder->weld_toggle_button("BTN_LIGHT_6"))
+ , m_aBtn_Light7(m_xBuilder->weld_toggle_button("BTN_LIGHT_7"))
+ , m_aBtn_Light8(m_xBuilder->weld_toggle_button("BTN_LIGHT_8"))
+ , m_xLB_LightSource(new ColorListBox(m_xBuilder->weld_menu_button("LB_LIGHTSOURCE"), [this]{ return m_pTopLevel; }))
+ , m_xBtn_LightSource_Color(m_xBuilder->weld_button("BTN_LIGHTSOURCE_COLOR"))
+ , m_xLB_AmbientLight(new ColorListBox(m_xBuilder->weld_menu_button("LB_AMBIENTLIGHT"), [this]{ return m_pTopLevel; }))
+ , m_xBtn_AmbientLight_Color(m_xBuilder->weld_button("BTN_AMBIENT_COLOR"))
+ , m_xHoriScale(m_xBuilder->weld_scale("hori"))
+ , m_xVertScale(m_xBuilder->weld_scale("vert"))
+ , m_xBtn_Corner(m_xBuilder->weld_button("corner"))
+ , m_xPreview(new Svx3DLightControl)
+ , m_xPreviewWnd(new weld::CustomWeld(*m_xBuilder, "CTL_LIGHT_PREVIEW", *m_xPreview))
+ , m_xCtl_Preview(new SvxLightCtl3D(*m_xPreview, *m_xHoriScale, *m_xVertScale, *m_xBtn_Corner))
+{
+ m_pLightSourceInfoList.reset(new LightSourceInfo[8]);
+ m_pLightSourceInfoList[0].pButton = &m_aBtn_Light1;
+ m_pLightSourceInfoList[1].pButton = &m_aBtn_Light2;
+ m_pLightSourceInfoList[2].pButton = &m_aBtn_Light3;
+ m_pLightSourceInfoList[3].pButton = &m_aBtn_Light4;
+ m_pLightSourceInfoList[4].pButton = &m_aBtn_Light5;
+ m_pLightSourceInfoList[5].pButton = &m_aBtn_Light6;
+ m_pLightSourceInfoList[6].pButton = &m_aBtn_Light7;
+ m_pLightSourceInfoList[7].pButton = &m_aBtn_Light8;
+
+ fillControlsFromModel(nullptr);
+
+ m_aBtn_Light1.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light2.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light3.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light4.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light5.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light6.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light7.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+ m_aBtn_Light8.connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl ) );
+
+ m_xLB_AmbientLight->SetSelectHdl( LINK( this, ThreeD_SceneIllumination_TabPage, SelectColorHdl ) );
+ m_xLB_LightSource->SetSelectHdl( LINK( this, ThreeD_SceneIllumination_TabPage, SelectColorHdl ) );
+
+ m_xBtn_AmbientLight_Color->connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ColorDialogHdl ) );
+ m_xBtn_LightSource_Color->connect_clicked( LINK( this, ThreeD_SceneIllumination_TabPage, ColorDialogHdl ) );
+
+ m_xCtl_Preview->SetUserInteractiveChangeCallback( LINK( this, ThreeD_SceneIllumination_TabPage, PreviewChangeHdl ) );
+ m_xCtl_Preview->SetUserSelectionChangeCallback( LINK( this, ThreeD_SceneIllumination_TabPage, PreviewSelectHdl ) );
+
+ ClickLightSourceButtonHdl(*m_aBtn_Light2.get_widget());
+
+ m_aModelChangeListener.startListening( uno::Reference< util::XModifyBroadcaster >(m_xSceneProperties, uno::UNO_QUERY) );
+}
+
+ThreeD_SceneIllumination_TabPage::~ThreeD_SceneIllumination_TabPage()
+{
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneIllumination_TabPage, fillControlsFromModel, void*, void)
+{
+ if( m_bInCommitToModel )//don't read own changes
+ return;
+
+ sal_Int32 nL=0;
+ for( nL=0; nL<8; nL++)
+ m_pLightSourceInfoList[nL].aLightSource = lcl_getLightSourceFromProperties( m_xSceneProperties, nL );
+ for( nL=0; nL<8; nL++)
+ m_pLightSourceInfoList[nL].initButtonFromSource();
+
+ lcl_selectColor( *m_xLB_AmbientLight, lcl_getAmbientColor( m_xSceneProperties ));
+
+ updatePreview();
+}
+
+void ThreeD_SceneIllumination_TabPage::applyLightSourceToModel( sal_uInt32 nLightNumber )
+{
+ ControllerLockGuardUNO aGuard( m_xChartModel );
+ m_bInCommitToModel = true;
+ sal_Int32 nIndex( nLightNumber );
+ lcl_setLightSource( m_xSceneProperties, m_pLightSourceInfoList[nIndex].aLightSource, nIndex );
+ m_bInCommitToModel = false;
+}
+
+void ThreeD_SceneIllumination_TabPage::applyLightSourcesToModel()
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ ControllerLockGuardUNO aGuard( m_xChartModel );
+ for( sal_Int32 nL=0; nL<8; nL++)
+ applyLightSourceToModel( nL );
+ m_aTimerTriggeredControllerLock.startTimer();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneIllumination_TabPage, PreviewChangeHdl, SvxLightCtl3D*, void)
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+
+ //update m_pLightSourceInfoList from preview
+ const SfxItemSet a3DLightAttributes(m_xCtl_Preview->GetSvx3DLightControl().Get3DAttributes());
+ LightSourceInfo* pInfo = &m_pLightSourceInfoList[0];
+
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_1).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[1];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_2).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[2];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_3).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[3];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_4).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[4];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_5).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[5];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_6).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[6];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_7).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7).GetValue());
+
+ pInfo = &m_pLightSourceInfoList[7];
+ pInfo->aLightSource.nDiffuseColor = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8).GetValue();
+ pInfo->aLightSource.bIsEnabled = a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTON_8).GetValue();
+ pInfo->aLightSource.aDirection = B3DVectorToDirection3D(a3DLightAttributes.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8).GetValue());
+
+ applyLightSourcesToModel();
+}
+
+IMPL_LINK_NOARG(ThreeD_SceneIllumination_TabPage, PreviewSelectHdl, SvxLightCtl3D*, void)
+{
+ sal_uInt32 nLightNumber = m_xCtl_Preview->GetSvx3DLightControl().GetSelectedLight();
+ if(nLightNumber<8)
+ {
+ LightButton* pButton = m_pLightSourceInfoList[nLightNumber].pButton;
+ if(!pButton->get_active())
+ ClickLightSourceButtonHdl(*pButton->get_widget());
+
+ applyLightSourcesToModel();
+ }
+}
+
+IMPL_LINK( ThreeD_SceneIllumination_TabPage, ColorDialogHdl, weld::Button&, rButton, void )
+{
+ bool bIsAmbientLight = (&rButton == m_xBtn_AmbientLight_Color.get());
+ ColorListBox* pListBox = bIsAmbientLight ? m_xLB_AmbientLight.get() : m_xLB_LightSource.get();
+
+ SvColorDialog aColorDlg;
+ aColorDlg.SetColor( pListBox->GetSelectEntryColor() );
+ if( aColorDlg.Execute(m_pTopLevel) != RET_OK )
+ return;
+
+ Color aColor( aColorDlg.GetColor());
+ lcl_selectColor( *pListBox, aColor );
+ if( bIsAmbientLight )
+ {
+ m_bInCommitToModel = true;
+ lcl_setAmbientColor( m_xSceneProperties, aColor );
+ m_bInCommitToModel = false;
+ }
+ else
+ {
+ //get active lightsource:
+ LightSourceInfo* pInfo = nullptr;
+ sal_Int32 nL=0;
+ for( nL=0; nL<8; nL++)
+ {
+ pInfo = &m_pLightSourceInfoList[nL];
+ if(pInfo->pButton->get_active())
+ break;
+ pInfo = nullptr;
+ }
+ if(pInfo)
+ applyLightSourceToModel( nL );
+ }
+ SelectColorHdl( *pListBox );
+}
+
+IMPL_LINK( ThreeD_SceneIllumination_TabPage, SelectColorHdl, ColorListBox&, rBox, void )
+{
+ ColorListBox* pListBox = &rBox;
+ if (pListBox == m_xLB_AmbientLight.get())
+ {
+ m_bInCommitToModel = true;
+ lcl_setAmbientColor( m_xSceneProperties, pListBox->GetSelectEntryColor());
+ m_bInCommitToModel = false;
+ }
+ else if (pListBox == m_xLB_LightSource.get())
+ {
+ //get active lightsource:
+ LightSourceInfo* pInfo = nullptr;
+ sal_Int32 nL=0;
+ for( nL=0; nL<8; nL++)
+ {
+ pInfo = &m_pLightSourceInfoList[nL];
+ if (pInfo->pButton->get_active())
+ break;
+ pInfo = nullptr;
+ }
+ if(pInfo)
+ {
+ pInfo->aLightSource.nDiffuseColor = pListBox->GetSelectEntryColor();
+ applyLightSourceToModel( nL );
+ }
+ }
+ updatePreview();
+}
+
+IMPL_LINK(ThreeD_SceneIllumination_TabPage, ClickLightSourceButtonHdl, weld::Button&, rBtn, void)
+{
+ LightButton* pButton = nullptr;
+ LightSourceInfo* pInfo = nullptr;
+ sal_Int32 nL=0;
+ for( nL=0; nL<8; nL++)
+ {
+ if (m_pLightSourceInfoList[nL].pButton->get_widget() == &rBtn)
+ {
+ pButton = m_pLightSourceInfoList[nL].pButton;
+ pInfo = &m_pLightSourceInfoList[nL];
+ break;
+ }
+ }
+
+ assert(pInfo);
+
+ bool bIsChecked = pInfo->pButton->get_prev_active();
+
+ ControllerLockGuardUNO aGuard( m_xChartModel );
+ for (sal_Int32 i = 0; i < 8; ++i)
+ {
+ LightButton* pLightButton = m_pLightSourceInfoList[i].pButton;
+ if (pLightButton == pButton)
+ {
+ pLightButton->set_active(true);
+ if (!pLightButton->get_widget()->has_focus())
+ pLightButton->get_widget()->grab_focus();
+ m_pLightSourceInfoList[i].pButton->set_prev_active(true);
+ }
+ else
+ {
+ pLightButton->set_active(false);
+ m_pLightSourceInfoList[i].pButton->set_prev_active(false);
+ }
+ }
+
+ //update light button
+ if (bIsChecked)
+ {
+ pButton->switchLightOn(!pButton->isLightOn());
+ pInfo->aLightSource.bIsEnabled=pButton->isLightOn();
+ applyLightSourceToModel( nL );
+ }
+
+ //update color list box
+ lcl_selectColor( *m_xLB_LightSource, pInfo->aLightSource.nDiffuseColor );
+ updatePreview();
+}
+
+void ThreeD_SceneIllumination_TabPage::updatePreview()
+{
+ SfxItemSet aItemSet(m_xCtl_Preview->GetSvx3DLightControl().Get3DAttributes());
+ LightSourceInfo* pInfo = &m_pLightSourceInfoList[0];
+
+ // AmbientColor
+ aItemSet.Put(makeSvx3DAmbientcolorItem(m_xLB_AmbientLight->GetSelectEntryColor()));
+
+ aItemSet.Put(makeSvx3DLightcolor1Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff1Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection1Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[1];
+ aItemSet.Put(makeSvx3DLightcolor2Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff2Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection2Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[2];
+ aItemSet.Put(makeSvx3DLightcolor3Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff3Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection3Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[3];
+ aItemSet.Put(makeSvx3DLightcolor4Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff4Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection4Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[4];
+ aItemSet.Put(makeSvx3DLightcolor5Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff5Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection5Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[5];
+ aItemSet.Put(makeSvx3DLightcolor6Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff6Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection6Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[6];
+ aItemSet.Put(makeSvx3DLightcolor7Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff7Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection7Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ pInfo = &m_pLightSourceInfoList[7];
+ aItemSet.Put(makeSvx3DLightcolor8Item(pInfo->aLightSource.nDiffuseColor));
+ aItemSet.Put(makeSvx3DLightOnOff8Item(pInfo->aLightSource.bIsEnabled));
+ aItemSet.Put(makeSvx3DLightDirection8Item(Direction3DToB3DVector(pInfo->aLightSource.aDirection)));
+
+ // set lights and ambient light
+ m_xCtl_Preview->GetSvx3DLightControl().Set3DAttributes(aItemSet);
+
+ // select light
+ for(sal_uInt32 a(0); a < 8; a++)
+ {
+ if (m_pLightSourceInfoList[a].pButton->get_active())
+ {
+ m_xCtl_Preview->GetSvx3DLightControl().SelectLight(a);
+ m_xCtl_Preview->CheckSelection();
+ break;
+ }
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_3D_SceneIllumination.hxx b/chart2/source/controller/dialogs/tp_3D_SceneIllumination.hxx
new file mode 100644
index 0000000000..98a1f32736
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_3D_SceneIllumination.hxx
@@ -0,0 +1,98 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <ModifyListenerCallBack.hxx>
+#include <TimerTriggeredControllerLock.hxx>
+#include <vcl/weld.hxx>
+#include <svx/dlgctl3d.hxx>
+#include <svx/float3d.hxx>
+
+namespace com::sun::star::beans
+{
+class XPropertySet;
+}
+
+class ColorListBox;
+
+namespace chart
+{
+struct LightSourceInfo;
+class ChartModel;
+
+class ThreeD_SceneIllumination_TabPage
+{
+public:
+ ThreeD_SceneIllumination_TabPage(weld::Container* pParent, weld::Window* pTopLevel,
+ css::uno::Reference<css::beans::XPropertySet> xSceneProperties,
+ const rtl::Reference<::chart::ChartModel>& xChartModel);
+ ~ThreeD_SceneIllumination_TabPage();
+
+private:
+ DECL_LINK(ClickLightSourceButtonHdl, weld::Button&, void);
+ DECL_LINK(SelectColorHdl, ColorListBox&, void);
+ DECL_LINK(ColorDialogHdl, weld::Button&, void);
+ DECL_LINK(PreviewChangeHdl, SvxLightCtl3D*, void);
+ DECL_LINK(PreviewSelectHdl, SvxLightCtl3D*, void);
+
+ void updatePreview();
+
+private:
+ DECL_LINK(fillControlsFromModel, void*, void);
+
+ void applyLightSourceToModel(sal_uInt32 nLightNumber);
+ void applyLightSourcesToModel();
+
+ std::unique_ptr<LightSourceInfo[]> m_pLightSourceInfoList;
+
+ css::uno::Reference<css::beans::XPropertySet> m_xSceneProperties;
+
+ TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
+
+ bool m_bInCommitToModel;
+
+ ModifyListenerCallBack m_aModelChangeListener;
+ rtl::Reference<::chart::ChartModel> m_xChartModel;
+
+ weld::Window* m_pTopLevel;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xContainer;
+ LightButton m_aBtn_Light1;
+ LightButton m_aBtn_Light2;
+ LightButton m_aBtn_Light3;
+ LightButton m_aBtn_Light4;
+ LightButton m_aBtn_Light5;
+ LightButton m_aBtn_Light6;
+ LightButton m_aBtn_Light7;
+ LightButton m_aBtn_Light8;
+ std::unique_ptr<ColorListBox> m_xLB_LightSource;
+ std::unique_ptr<weld::Button> m_xBtn_LightSource_Color;
+ std::unique_ptr<ColorListBox> m_xLB_AmbientLight;
+ std::unique_ptr<weld::Button> m_xBtn_AmbientLight_Color;
+ std::unique_ptr<weld::Scale> m_xHoriScale;
+ std::unique_ptr<weld::Scale> m_xVertScale;
+ std::unique_ptr<weld::Button> m_xBtn_Corner;
+ std::unique_ptr<Svx3DLightControl> m_xPreview;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWnd;
+ std::unique_ptr<SvxLightCtl3D> m_xCtl_Preview;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_AxisLabel.cxx b/chart2/source/controller/dialogs/tp_AxisLabel.cxx
new file mode 100644
index 0000000000..33faff6c53
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_AxisLabel.cxx
@@ -0,0 +1,300 @@
+/* -*- 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 .
+ */
+
+#include "tp_AxisLabel.hxx"
+
+#include <chartview/ChartSfxItemIds.hxx>
+#include <TextDirectionListBox.hxx>
+
+#include <svx/chrtitem.hxx>
+#include <svx/sdangitm.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+
+namespace chart
+{
+
+SchAxisLabelTabPage::SchAxisLabelTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_axisLabel.ui", "AxisLabelTabPage", &rInAttrs)
+ , m_bShowStaggeringControls( true )
+ , m_nInitialDegrees( 0 )
+ , m_bHasInitialDegrees( true )
+ , m_bInitialStacking( false )
+ , m_bHasInitialStacking( true )
+ , m_bComplexCategories( false )
+ , m_xCbShowDescription(m_xBuilder->weld_check_button("showlabelsCB"))
+ , m_xFlOrder(m_xBuilder->weld_label("orderL"))
+ , m_xRbSideBySide(m_xBuilder->weld_radio_button("tile"))
+ , m_xRbUpDown(m_xBuilder->weld_radio_button("odd"))
+ , m_xRbDownUp(m_xBuilder->weld_radio_button("even"))
+ , m_xRbAuto(m_xBuilder->weld_radio_button("auto"))
+ , m_xFlTextFlow(m_xBuilder->weld_label("textflowL"))
+ , m_xCbTextOverlap(m_xBuilder->weld_check_button("overlapCB"))
+ , m_xCbTextBreak(m_xBuilder->weld_check_button("breakCB"))
+ , m_xFtABCD(m_xBuilder->weld_label("labelABCD"))
+ , m_xFtRotate(m_xBuilder->weld_label("degreeL"))
+ , m_xNfRotate(m_xBuilder->weld_metric_spin_button("OrientDegree", FieldUnit::DEGREE))
+ , m_xCbStacked(m_xBuilder->weld_check_button("stackedCB"))
+ , m_xFtTextDirection(m_xBuilder->weld_label("textdirL"))
+ , m_aLbTextDirection(m_xBuilder->weld_combo_box("textdirLB"))
+ , m_xCtrlDial(new svx::DialControl)
+ , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, "dialCtrl", *m_xCtrlDial))
+{
+ m_xCtrlDial->SetText(m_xFtABCD->get_label());
+ m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
+ m_xCtrlDialWin->set_sensitive(true);
+ m_xNfRotate->set_sensitive(true);
+ m_xCbStacked->set_sensitive(true);
+ m_xFtRotate->set_sensitive(true);
+
+ m_xCbStacked->connect_toggled(LINK(this, SchAxisLabelTabPage, StackedToggleHdl));
+ m_xCbShowDescription->connect_toggled(LINK(this, SchAxisLabelTabPage, ToggleShowLabel));
+}
+
+SchAxisLabelTabPage::~SchAxisLabelTabPage()
+{
+ m_xCtrlDialWin.reset();
+ m_xCtrlDial.reset();
+}
+
+std::unique_ptr<SfxTabPage> SchAxisLabelTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SchAxisLabelTabPage>(pPage, pController, *rAttrs);
+}
+
+bool SchAxisLabelTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ bool bStacked = false;
+ if (m_xCbStacked->get_state() != TRISTATE_INDET )
+ {
+ bStacked = m_xCbStacked->get_state() == TRISTATE_TRUE;
+ if( !m_bHasInitialStacking || (bStacked != m_bInitialStacking) )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_TEXT_STACKED, bStacked ) );
+ }
+
+ if( m_xCtrlDial->HasRotation() )
+ {
+ Degree100 nDegrees = bStacked ? 0_deg100 : m_xCtrlDial->GetRotation();
+ if( !m_bHasInitialDegrees || (nDegrees != m_nInitialDegrees) )
+ rOutAttrs->Put( SdrAngleItem( SCHATTR_TEXT_DEGREES, nDegrees ) );
+ }
+
+ if( m_bShowStaggeringControls )
+ {
+ SvxChartTextOrder eOrder = SvxChartTextOrder::SideBySide;
+ bool bRadioButtonChecked = true;
+
+ if( m_xRbUpDown->get_active())
+ eOrder = SvxChartTextOrder::UpDown;
+ else if( m_xRbDownUp->get_active())
+ eOrder = SvxChartTextOrder::DownUp;
+ else if( m_xRbAuto->get_active())
+ eOrder = SvxChartTextOrder::Auto;
+ else if( m_xRbSideBySide->get_active())
+ eOrder = SvxChartTextOrder::SideBySide;
+ else
+ bRadioButtonChecked = false;
+
+ if( bRadioButtonChecked )
+ rOutAttrs->Put( SvxChartTextOrderItem( eOrder, SCHATTR_AXIS_LABEL_ORDER ));
+ }
+
+ if( m_xCbTextOverlap->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_AXIS_LABEL_OVERLAP, m_xCbTextOverlap->get_active() ) );
+ if( m_xCbTextBreak->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_AXIS_LABEL_BREAK, m_xCbTextBreak->get_active() ) );
+ if( m_xCbShowDescription->get_state() != TRISTATE_INDET )
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_AXIS_SHOWDESCR, m_xCbShowDescription->get_active() ) );
+
+ if (m_aLbTextDirection.get_active() != -1)
+ rOutAttrs->Put( SvxFrameDirectionItem( m_aLbTextDirection.get_active_id(), EE_PARA_WRITINGDIR ) );
+
+ return true;
+}
+
+void SchAxisLabelTabPage::Reset( const SfxItemSet* rInAttrs )
+{
+ const SfxPoolItem* pPoolItem = nullptr;
+
+ // show description
+ SfxItemState aState = rInAttrs->GetItemState( SCHATTR_AXIS_SHOWDESCR, false, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCbShowDescription->set_state( TRISTATE_INDET );
+ }
+ else
+ {
+ bool bCheck = false;
+ if( aState == SfxItemState::SET )
+ bCheck = static_cast< const SfxBoolItem * >( pPoolItem )->GetValue();
+ m_xCbShowDescription->set_active( bCheck );
+
+ if( aState != SfxItemState::DEFAULT && aState != SfxItemState::SET )
+ m_xCbShowDescription->hide();
+ }
+
+ // Rotation as orient item or in degrees ----------
+
+ // check new degree item
+ m_nInitialDegrees = 0_deg100;
+ aState = rInAttrs->GetItemState( SCHATTR_TEXT_DEGREES, false, &pPoolItem );
+ if( aState == SfxItemState::SET )
+ m_nInitialDegrees = static_cast< const SdrAngleItem * >( pPoolItem )->GetValue();
+
+ m_bHasInitialDegrees = aState != SfxItemState::DONTCARE;
+ if( m_bHasInitialDegrees )
+ m_xCtrlDial->SetRotation( m_nInitialDegrees );
+ else
+ m_xCtrlDial->SetNoRotation();
+
+ // check stacked item
+ m_bInitialStacking = false;
+ aState = rInAttrs->GetItemState( SCHATTR_TEXT_STACKED, false, &pPoolItem );
+ if( aState == SfxItemState::SET )
+ m_bInitialStacking = static_cast< const SfxBoolItem * >( pPoolItem )->GetValue();
+
+ m_bHasInitialStacking = aState != SfxItemState::DONTCARE;
+ if( m_bHasInitialDegrees )
+ m_xCbStacked->set_state(m_bInitialStacking ? TRISTATE_TRUE : TRISTATE_FALSE);
+ else
+ m_xCbStacked->set_state(TRISTATE_INDET);
+ StackedToggleHdl(*m_xCbStacked);
+
+ if( const SvxFrameDirectionItem* pDirectionItem = rInAttrs->GetItemIfSet( EE_PARA_WRITINGDIR ) )
+ m_aLbTextDirection.set_active_id( pDirectionItem->GetValue() );
+
+ // Text overlap ----------
+ aState = rInAttrs->GetItemState( SCHATTR_AXIS_LABEL_OVERLAP, false, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCbTextOverlap->set_state( TRISTATE_INDET );
+ }
+ else
+ {
+ bool bCheck = false;
+ if( aState == SfxItemState::SET )
+ bCheck = static_cast< const SfxBoolItem * >( pPoolItem )->GetValue();
+ m_xCbTextOverlap->set_active( bCheck );
+
+ if( aState != SfxItemState::DEFAULT && aState != SfxItemState::SET )
+ m_xCbTextOverlap->hide();
+ }
+
+ // text break ----------
+ aState = rInAttrs->GetItemState( SCHATTR_AXIS_LABEL_BREAK, false, &pPoolItem );
+ if( aState == SfxItemState::DONTCARE )
+ {
+ m_xCbTextBreak->set_state( TRISTATE_INDET );
+ }
+ else
+ {
+ bool bCheck = false;
+ if( aState == SfxItemState::SET )
+ bCheck = static_cast< const SfxBoolItem * >( pPoolItem )->GetValue();
+ m_xCbTextBreak->set_active( bCheck );
+
+ if( aState != SfxItemState::DEFAULT && aState != SfxItemState::SET )
+ {
+ m_xCbTextBreak->hide();
+ if( ! m_xCbTextOverlap->get_visible() )
+ m_xFlTextFlow->hide();
+ }
+ }
+
+ // text order ----------
+ if( m_bShowStaggeringControls )
+ {
+ if( const SvxChartTextOrderItem* pOrderItem = rInAttrs->GetItemIfSet( SCHATTR_AXIS_LABEL_ORDER, false ) )
+ {
+ SvxChartTextOrder eOrder = pOrderItem->GetValue();
+
+ switch( eOrder )
+ {
+ case SvxChartTextOrder::SideBySide:
+ m_xRbSideBySide->set_active(true);
+ break;
+ case SvxChartTextOrder::UpDown:
+ m_xRbUpDown->set_active(true);
+ break;
+ case SvxChartTextOrder::DownUp:
+ m_xRbDownUp->set_active(true);
+ break;
+ case SvxChartTextOrder::Auto:
+ m_xRbAuto->set_active(true);
+ break;
+ }
+ }
+ }
+
+ ToggleShowLabel(*m_xCbShowDescription);
+}
+
+void SchAxisLabelTabPage::ShowStaggeringControls( bool bShowStaggeringControls )
+{
+ m_bShowStaggeringControls = bShowStaggeringControls;
+
+ if( !m_bShowStaggeringControls )
+ {
+ m_xRbSideBySide->hide();
+ m_xRbUpDown->hide();
+ m_xRbDownUp->hide();
+ m_xRbAuto->hide();
+ m_xFlOrder->hide();
+ }
+}
+
+void SchAxisLabelTabPage::SetComplexCategories( bool bComplexCategories )
+{
+ m_bComplexCategories = bComplexCategories;
+}
+
+// event handling routines
+
+IMPL_LINK_NOARG(SchAxisLabelTabPage, StackedToggleHdl, weld::Toggleable&, void)
+{
+ bool bActive = m_xCbStacked->get_active() && m_xCbStacked->get_sensitive();
+ m_xNfRotate->set_sensitive(!bActive);
+ m_xCtrlDialWin->set_sensitive(!bActive);
+ m_xCtrlDial->StyleUpdated();
+ m_xFtRotate->set_sensitive(!bActive);
+}
+
+IMPL_LINK_NOARG(SchAxisLabelTabPage, ToggleShowLabel, weld::Toggleable&, void)
+{
+ bool bEnable = ( m_xCbShowDescription->get_state() != TRISTATE_FALSE );
+
+ m_xCbStacked->set_sensitive(bEnable);
+ StackedToggleHdl(*m_xCbStacked);
+
+ m_xFlOrder->set_sensitive( bEnable );
+ m_xRbSideBySide->set_sensitive( bEnable );
+ m_xRbUpDown->set_sensitive( bEnable );
+ m_xRbDownUp->set_sensitive( bEnable );
+ m_xRbAuto->set_sensitive( bEnable );
+
+ m_xFlTextFlow->set_sensitive( bEnable );
+ m_xCbTextOverlap->set_sensitive( bEnable && !m_bComplexCategories );
+ m_xCbTextBreak->set_sensitive( bEnable );
+
+ m_xFtTextDirection->set_sensitive( bEnable );
+ m_aLbTextDirection.set_sensitive( bEnable );
+}
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_AxisLabel.hxx b/chart2/source/controller/dialogs/tp_AxisLabel.hxx
new file mode 100644
index 0000000000..75704ec4e4
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_AxisLabel.hxx
@@ -0,0 +1,83 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/dialcontrol.hxx>
+#include <tools/degree.hxx>
+#include <TextDirectionListBox.hxx>
+
+namespace weld {
+ class CheckButton;
+ class CustomWeld;
+ class Label;
+ class RadioButton;
+ class SpinButton;
+ class ToggleButton;
+}
+
+namespace chart
+{
+
+class SchAxisLabelTabPage : public SfxTabPage
+{
+private:
+ bool m_bShowStaggeringControls;
+
+ Degree100 m_nInitialDegrees;
+ bool m_bHasInitialDegrees; /// false = DialControl in tristate
+ bool m_bInitialStacking;
+ bool m_bHasInitialStacking; /// false = checkbox in tristate
+ bool m_bComplexCategories;
+
+ std::unique_ptr<weld::CheckButton> m_xCbShowDescription;
+ std::unique_ptr<weld::Label> m_xFlOrder;
+ std::unique_ptr<weld::RadioButton> m_xRbSideBySide;
+ std::unique_ptr<weld::RadioButton> m_xRbUpDown;
+ std::unique_ptr<weld::RadioButton> m_xRbDownUp;
+ std::unique_ptr<weld::RadioButton> m_xRbAuto;
+ std::unique_ptr<weld::Label> m_xFlTextFlow;
+ std::unique_ptr<weld::CheckButton> m_xCbTextOverlap;
+ std::unique_ptr<weld::CheckButton> m_xCbTextBreak;
+ std::unique_ptr<weld::Label> m_xFtABCD;
+ std::unique_ptr<weld::Label> m_xFtRotate;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfRotate;
+ std::unique_ptr<weld::CheckButton> m_xCbStacked;
+ std::unique_ptr<weld::Label> m_xFtTextDirection;
+ TextDirectionListBox m_aLbTextDirection;
+ std::unique_ptr<svx::DialControl> m_xCtrlDial;
+ std::unique_ptr<weld::CustomWeld> m_xCtrlDialWin;
+
+ DECL_LINK(StackedToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(ToggleShowLabel, weld::Toggleable&, void);
+
+public:
+ SchAxisLabelTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SchAxisLabelTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+ void ShowStaggeringControls( bool bShowStaggeringControls );
+ void SetComplexCategories( bool bComplexCategories );
+};
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_AxisPositions.cxx b/chart2/source/controller/dialogs/tp_AxisPositions.cxx
new file mode 100644
index 0000000000..4e3e4bb759
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_AxisPositions.cxx
@@ -0,0 +1,320 @@
+/* -*- 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 .
+ */
+
+#include "tp_AxisPositions.hxx"
+
+#include <chartview/ChartSfxItemIds.hxx>
+#include <AxisHelper.hxx>
+
+#include <rtl/math.hxx>
+#include <svx/chrtitem.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/formatter.hxx>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+AxisPositionsTabPage::AxisPositionsTabPage(weld::Container* pPage, weld::DialogController* pController,const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_AxisPositions.ui", "tp_AxisPositions", &rInAttrs)
+ , m_pNumFormatter(nullptr)
+ , m_bCrossingAxisIsCategoryAxis(false)
+ , m_bSupportAxisPositioning(false)
+ , m_bSupportCategoryPositioning(false)
+ , m_xFL_AxisLine(m_xBuilder->weld_frame("FL_AXIS_LINE"))
+ , m_xLB_CrossesAt(m_xBuilder->weld_combo_box("LB_CROSSES_OTHER_AXIS_AT"))
+ , m_xED_CrossesAt(m_xBuilder->weld_formatted_spin_button("EDT_CROSSES_OTHER_AXIS_AT"))
+ , m_xED_CrossesAtCategory(m_xBuilder->weld_combo_box( "EDT_CROSSES_OTHER_AXIS_AT_CATEGORY"))
+ , m_xFL_Position(m_xBuilder->weld_frame("FL_POSITION"))
+ , m_xRB_On(m_xBuilder->weld_radio_button("RB_ON"))
+ , m_xRB_Between(m_xBuilder->weld_radio_button("RB_BETWEEN"))
+ , m_xFL_Labels(m_xBuilder->weld_frame("FL_LABELS"))
+ , m_xLB_PlaceLabels(m_xBuilder->weld_combo_box("LB_PLACE_LABELS"))
+ , m_xCB_TicksInner(m_xBuilder->weld_check_button("CB_TICKS_INNER"))
+ , m_xCB_TicksOuter(m_xBuilder->weld_check_button("CB_TICKS_OUTER"))
+ , m_xCB_MinorInner(m_xBuilder->weld_check_button("CB_MINOR_INNER"))
+ , m_xCB_MinorOuter(m_xBuilder->weld_check_button("CB_MINOR_OUTER"))
+ , m_xBxPlaceTicks(m_xBuilder->weld_widget("boxPLACE_TICKS"))
+ , m_xLB_PlaceTicks(m_xBuilder->weld_combo_box("LB_PLACE_TICKS"))
+{
+ m_xLB_CrossesAt->connect_changed(LINK(this, AxisPositionsTabPage, CrossesAtSelectHdl));
+ m_xLB_PlaceLabels->connect_changed(LINK(this, AxisPositionsTabPage, PlaceLabelsSelectHdl));
+
+ Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter();
+ rCrossFormatter.ClearMinValue();
+ rCrossFormatter.ClearMaxValue();
+ Formatter& rDistanceFormatter = m_xED_CrossesAt->GetFormatter();
+ rDistanceFormatter.ClearMinValue();
+ rDistanceFormatter.ClearMaxValue();
+}
+
+AxisPositionsTabPage::~AxisPositionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> AxisPositionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<AxisPositionsTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool AxisPositionsTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ // axis line
+ sal_Int32 nPos = m_xLB_CrossesAt->get_active();
+ rOutAttrs->Put( SfxInt32Item( SCHATTR_AXIS_POSITION, nPos+1 ));
+ if( nPos==2 )
+ {
+ Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter();
+ double fCrossover = rCrossFormatter.GetValue();
+ if( m_bCrossingAxisIsCategoryAxis )
+ fCrossover = m_xED_CrossesAtCategory->get_active()+1;
+ rOutAttrs->Put(SvxDoubleItem(fCrossover,SCHATTR_AXIS_POSITION_VALUE));
+ }
+
+ // shifted category position
+ if (m_xFL_Position->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_SHIFTED_CATEGORY_POSITION, m_xRB_Between->get_active()));
+
+ // labels
+ sal_Int32 nLabelPos = m_xLB_PlaceLabels->get_active();
+ if (nLabelPos != -1)
+ rOutAttrs->Put( SfxInt32Item( SCHATTR_AXIS_LABEL_POSITION, nLabelPos ));
+
+ // tick marks
+ sal_Int32 nTicks=0;
+ sal_Int32 nMinorTicks=0;
+
+ if(m_xCB_MinorInner->get_active())
+ nMinorTicks|=CHAXIS_MARK_INNER;
+ if(m_xCB_MinorOuter->get_active())
+ nMinorTicks|=CHAXIS_MARK_OUTER;
+ if(m_xCB_TicksInner->get_active())
+ nTicks|=CHAXIS_MARK_INNER;
+ if(m_xCB_TicksOuter->get_active())
+ nTicks|=CHAXIS_MARK_OUTER;
+
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_TICKS,nTicks));
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_HELPTICKS,nMinorTicks));
+
+ sal_Int32 nMarkPos = m_xLB_PlaceTicks->get_active();
+ if (nMarkPos != -1)
+ rOutAttrs->Put( SfxInt32Item( SCHATTR_AXIS_MARK_POSITION, nMarkPos ));
+
+ return true;
+}
+
+void AxisPositionsTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ //init and enable controls
+ m_xED_CrossesAt->set_visible( !m_bCrossingAxisIsCategoryAxis );
+ m_xED_CrossesAtCategory->set_visible( m_bCrossingAxisIsCategoryAxis );
+ if (m_bCrossingAxisIsCategoryAxis)
+ {
+ for( auto const & cat : std::as_const(m_aCategories) )
+ m_xED_CrossesAtCategory->append_text(cat);
+ }
+
+ if( m_xLB_CrossesAt->get_count() > 3 )
+ {
+ if( m_bCrossingAxisIsCategoryAxis )
+ m_xLB_CrossesAt->remove(2);
+ else
+ m_xLB_CrossesAt->remove(3);
+ }
+
+ //fill controls
+
+ //axis line
+ if(SfxInt32Item const * pPositionItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_POSITION))
+ {
+ bool bZero = false;
+ sal_Int32 nPos = pPositionItem->GetValue();
+ if(nPos==0)
+ {
+ //switch to value
+ bZero = true;
+ nPos = 2;
+ }
+ else
+ nPos--;
+
+ if( nPos < m_xLB_CrossesAt->get_count() )
+ m_xLB_CrossesAt->set_active( nPos );
+ CrossesAtSelectHdl( *m_xLB_CrossesAt );
+
+ const SvxDoubleItem* pPosValueItem;
+ if( (pPosValueItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_POSITION_VALUE)) || bZero )
+ {
+ double fCrossover = 0.0;
+ if( !bZero )
+ fCrossover = pPosValueItem->GetValue();
+ if( m_bCrossingAxisIsCategoryAxis )
+ m_xED_CrossesAtCategory->set_active( static_cast<sal_uInt16>(::rtl::math::round(fCrossover-1.0)) );
+ else
+ {
+ Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter();
+ rCrossFormatter.SetValue(fCrossover);
+ }
+ }
+ else
+ {
+ m_xED_CrossesAtCategory->set_active(-1);
+ m_xED_CrossesAt->set_text("");
+ }
+ }
+ else
+ {
+ m_xLB_CrossesAt->set_active(-1);
+ m_xED_CrossesAt->set_sensitive( false );
+ }
+
+ // shifted category position
+ const SfxBoolItem* pCatPosItem;
+ if (m_bSupportCategoryPositioning && (pCatPosItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_SHIFTED_CATEGORY_POSITION)))
+ {
+ if (pCatPosItem->GetValue())
+ m_xRB_Between->set_active(true);
+ else
+ m_xRB_On->set_active(true);
+ }
+ else
+ m_xFL_Position->hide();
+
+ // Labels
+ if( const SfxInt32Item* pLabelPosItem = rInAttrs->GetItemIfSet( SCHATTR_AXIS_LABEL_POSITION, false) )
+ {
+ sal_Int32 nPos = pLabelPosItem->GetValue();
+ if( nPos < m_xLB_PlaceLabels->get_count() )
+ m_xLB_PlaceLabels->set_active( nPos );
+ }
+ else
+ m_xLB_PlaceLabels->set_active(-1);
+ PlaceLabelsSelectHdl( *m_xLB_PlaceLabels );
+
+ // Tick marks
+ tools::Long nTicks = 0, nMinorTicks = 0;
+ if (const SfxInt32Item* pTicksItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_TICKS))
+ nTicks = pTicksItem->GetValue();
+ if (const SfxInt32Item* pHelpTicksItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_HELPTICKS))
+ nMinorTicks = pHelpTicksItem->GetValue();
+
+ m_xCB_TicksInner->set_active(bool(nTicks&CHAXIS_MARK_INNER));
+ m_xCB_TicksOuter->set_active(bool(nTicks&CHAXIS_MARK_OUTER));
+ m_xCB_MinorInner->set_active(bool(nMinorTicks&CHAXIS_MARK_INNER));
+ m_xCB_MinorOuter->set_active(bool(nMinorTicks&CHAXIS_MARK_OUTER));
+
+ // Tick position
+ if( const SfxInt32Item* pMarkPosItem = rInAttrs->GetItemIfSet( SCHATTR_AXIS_MARK_POSITION, false) )
+ {
+ sal_Int32 nPos = pMarkPosItem->GetValue();
+ if( nPos < m_xLB_PlaceTicks->get_count() )
+ m_xLB_PlaceTicks->set_active( nPos );
+ }
+ else
+ m_xLB_PlaceTicks->set_active(-1);
+
+ if( !m_bSupportAxisPositioning )
+ {
+ m_xFL_AxisLine->hide();
+ m_xFL_Labels->hide();
+ m_xBxPlaceTicks->hide();
+ }
+ else if( !AxisHelper::isAxisPositioningEnabled() )
+ {
+ m_xFL_AxisLine->set_sensitive(false);
+ m_xFL_Labels->set_sensitive(false);
+ m_xBxPlaceTicks->set_sensitive(false);
+ //todo: maybe set a special help id to all those controls
+ }
+}
+
+DeactivateRC AxisPositionsTabPage::DeactivatePage(SfxItemSet* pItemSet)
+{
+ if( pItemSet )
+ FillItemSet( pItemSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void AxisPositionsTabPage::SetNumFormatter( SvNumberFormatter* pFormatter )
+{
+ m_pNumFormatter = pFormatter;
+ Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter();
+ rCrossFormatter.SetFormatter(m_pNumFormatter);
+ rCrossFormatter.UseInputStringForFormatting();
+
+ if( const SfxUInt32Item* pNumFormatItem = GetItemSet().GetItemIfSet(SCHATTR_AXIS_CROSSING_MAIN_AXIS_NUMBERFORMAT) )
+ {
+ sal_uInt32 nFmt = pNumFormatItem->GetValue();
+ rCrossFormatter.SetFormatKey(nFmt);
+ }
+}
+
+void AxisPositionsTabPage::SetCrossingAxisIsCategoryAxis( bool bCrossingAxisIsCategoryAxis )
+{
+ m_bCrossingAxisIsCategoryAxis = bCrossingAxisIsCategoryAxis;
+}
+
+void AxisPositionsTabPage::SetCategories( const css::uno::Sequence< OUString >& rCategories )
+{
+ m_aCategories = rCategories;
+}
+
+void AxisPositionsTabPage::SupportAxisPositioning( bool bSupportAxisPositioning )
+{
+ m_bSupportAxisPositioning = bSupportAxisPositioning;
+}
+
+void AxisPositionsTabPage::SupportCategoryPositioning( bool bSupportCategoryPositioning )
+{
+ m_bSupportCategoryPositioning = bSupportCategoryPositioning;
+}
+
+IMPL_LINK_NOARG(AxisPositionsTabPage, CrossesAtSelectHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLB_CrossesAt->get_active();
+ m_xED_CrossesAt->set_visible( (nPos==2) && !m_bCrossingAxisIsCategoryAxis );
+ m_xED_CrossesAtCategory->set_visible( (nPos==2) && m_bCrossingAxisIsCategoryAxis );
+
+ if (m_xED_CrossesAt->get_text().isEmpty())
+ m_xED_CrossesAt->GetFormatter().SetValue(0.0);
+ if (m_xED_CrossesAtCategory->get_active() == -1 && m_xED_CrossesAtCategory->get_count())
+ m_xED_CrossesAtCategory->set_active(0);
+
+ PlaceLabelsSelectHdl(*m_xLB_PlaceLabels);
+}
+
+IMPL_LINK_NOARG(AxisPositionsTabPage, PlaceLabelsSelectHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nLabelPos = m_xLB_PlaceLabels->get_active();
+
+ bool bEnableTickmarkPlacement = (nLabelPos>1);
+ if( bEnableTickmarkPlacement )
+ {
+ sal_Int32 nAxisPos = m_xLB_CrossesAt->get_active();
+ if( nLabelPos-2 == nAxisPos )
+ bEnableTickmarkPlacement=false;
+ }
+ m_xBxPlaceTicks->set_sensitive(bEnableTickmarkPlacement);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_AxisPositions.hxx b/chart2/source/controller/dialogs/tp_AxisPositions.hxx
new file mode 100644
index 0000000000..86f749a268
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_AxisPositions.hxx
@@ -0,0 +1,83 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace chart
+{
+class AxisPositionsTabPage : public SfxTabPage
+{
+public:
+ AxisPositionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~AxisPositionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pItemSet) override;
+
+ void SetNumFormatter(SvNumberFormatter* pFormatter);
+
+ void SetCrossingAxisIsCategoryAxis(bool bCrossingAxisIsCategoryAxis);
+ void SetCategories(const css::uno::Sequence<OUString>& rCategories);
+
+ void SupportAxisPositioning(bool bSupportAxisPositioning);
+ void SupportCategoryPositioning(bool bSupportCategoryPositioning);
+
+private: //methods:
+ DECL_LINK(CrossesAtSelectHdl, weld::ComboBox&, void);
+ DECL_LINK(PlaceLabelsSelectHdl, weld::ComboBox&, void);
+
+private: //member:
+ SvNumberFormatter* m_pNumFormatter;
+
+ bool m_bCrossingAxisIsCategoryAxis;
+ css::uno::Sequence<OUString> m_aCategories;
+
+ bool m_bSupportAxisPositioning;
+ bool m_bSupportCategoryPositioning;
+
+ std::unique_ptr<weld::Frame> m_xFL_AxisLine;
+ std::unique_ptr<weld::ComboBox> m_xLB_CrossesAt;
+ std::unique_ptr<weld::FormattedSpinButton> m_xED_CrossesAt;
+ std::unique_ptr<weld::ComboBox> m_xED_CrossesAtCategory;
+
+ std::unique_ptr<weld::Frame> m_xFL_Position;
+ std::unique_ptr<weld::RadioButton> m_xRB_On;
+ std::unique_ptr<weld::RadioButton> m_xRB_Between;
+
+ std::unique_ptr<weld::Frame> m_xFL_Labels;
+ std::unique_ptr<weld::ComboBox> m_xLB_PlaceLabels;
+
+ std::unique_ptr<weld::CheckButton> m_xCB_TicksInner;
+ std::unique_ptr<weld::CheckButton> m_xCB_TicksOuter;
+
+ std::unique_ptr<weld::CheckButton> m_xCB_MinorInner;
+ std::unique_ptr<weld::CheckButton> m_xCB_MinorOuter;
+
+ std::unique_ptr<weld::Widget> m_xBxPlaceTicks;
+ std::unique_ptr<weld::ComboBox> m_xLB_PlaceTicks;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_ChartType.cxx b/chart2/source/controller/dialogs/tp_ChartType.cxx
new file mode 100644
index 0000000000..e0ddd62cd6
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_ChartType.cxx
@@ -0,0 +1,385 @@
+/* -*- 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 .
+ */
+
+#include "tp_ChartType.hxx"
+#include <ChartResourceGroups.hxx>
+#include <ChartTypeManager.hxx>
+#include <strings.hrc>
+#include <ResId.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <unonames.hxx>
+
+#include <svtools/valueset.hxx>
+
+#include <utility>
+#include <vcl/weld.hxx>
+#include <vcl/outdev.hxx>
+#include <comphelper/diagnose_ex.hxx>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+ChartTypeTabPage::ChartTypeTabPage(weld::Container* pPage, weld::DialogController* pController, rtl::Reference<::chart::ChartModel> xChartModel,
+ bool bShowDescription)
+ : OWizardPage(pPage, pController, "modules/schart/ui/tp_ChartType.ui", "tp_ChartType")
+ , m_pDim3DLookResourceGroup( new Dim3DLookResourceGroup(m_xBuilder.get()) )
+ , m_pStackingResourceGroup( new StackingResourceGroup(m_xBuilder.get()) )
+ , m_pSplineResourceGroup( new SplineResourceGroup(m_xBuilder.get(), pController->getDialog()) )
+ , m_pGeometryResourceGroup( new GeometryResourceGroup(m_xBuilder.get()) )
+ , m_pSortByXValuesResourceGroup( new SortByXValuesResourceGroup(m_xBuilder.get()) )
+ , m_xChartModel(std::move( xChartModel ))
+ , m_aChartTypeDialogControllerList(0)
+ , m_pCurrentMainType(nullptr)
+ , m_nChangingCalls(0)
+ , m_aTimerTriggeredControllerLock( m_xChartModel )
+ , m_xFT_ChooseType(m_xBuilder->weld_label("FT_CAPTION_FOR_WIZARD"))
+ , m_xMainTypeList(m_xBuilder->weld_tree_view("charttype"))
+ , m_xSubTypeList(new ValueSet(m_xBuilder->weld_scrolled_window("subtypewin", true)))
+ , m_xSubTypeListWin(new weld::CustomWeld(*m_xBuilder, "subtype", *m_xSubTypeList))
+{
+ Size aSize(m_xSubTypeList->GetDrawingArea()->get_ref_device().LogicToPixel(Size(150, 50), MapMode(MapUnit::MapAppFont)));
+ m_xSubTypeListWin->set_size_request(aSize.Width(), aSize.Height());
+
+ if (bShowDescription)
+ {
+ m_xFT_ChooseType->show();
+ }
+ else
+ {
+ m_xFT_ChooseType->hide();
+ }
+
+ SetPageTitle(SchResId(STR_PAGE_CHARTTYPE));
+
+ m_xMainTypeList->connect_changed(LINK(this, ChartTypeTabPage, SelectMainTypeHdl));
+ m_xSubTypeList->SetSelectHdl( LINK( this, ChartTypeTabPage, SelectSubTypeHdl ) );
+
+ m_xSubTypeList->SetStyle(m_xSubTypeList->GetStyle() |
+ WB_ITEMBORDER | WB_DOUBLEBORDER | WB_NAMEFIELD | WB_FLATVALUESET | WB_3DLOOK );
+ m_xSubTypeList->SetColCount(4);
+ m_xSubTypeList->SetLineCount(1);
+
+ bool bEnableComplexChartTypes = true;
+ uno::Reference< beans::XPropertySet > xProps( static_cast<cppu::OWeakObject*>(m_xChartModel.get()), uno::UNO_QUERY );
+ if ( xProps.is() )
+ {
+ try
+ {
+ xProps->getPropertyValue("EnableComplexChartTypes") >>= bEnableComplexChartTypes;
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("chart2", "" );
+ }
+ }
+
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<ColumnChartDialogController>());
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<BarChartDialogController>());
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<PieChartDialogController>());
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<AreaChartDialogController>());
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<LineChartDialogController>());
+ if (bEnableComplexChartTypes)
+ {
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<XYChartDialogController>());
+ m_aChartTypeDialogControllerList.push_back(
+ std::make_unique<BubbleChartDialogController>());
+ }
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<NetChartDialogController>());
+ if (bEnableComplexChartTypes)
+ {
+ m_aChartTypeDialogControllerList.push_back(std::make_unique<StockChartDialogController>());
+ }
+ m_aChartTypeDialogControllerList.push_back(
+ std::make_unique<CombiColumnLineChartDialogController>());
+
+ for (auto const& elem : m_aChartTypeDialogControllerList)
+ {
+ m_xMainTypeList->append("", elem->getName(), elem->getImage());
+ elem->setChangeListener( this );
+ }
+
+ m_xMainTypeList->set_size_request(m_xMainTypeList->get_preferred_size().Width(), -1);
+
+ m_pDim3DLookResourceGroup->setChangeListener( this );
+ m_pStackingResourceGroup->setChangeListener( this );
+ m_pSplineResourceGroup->setChangeListener( this );
+ m_pGeometryResourceGroup->setChangeListener( this );
+ m_pSortByXValuesResourceGroup->setChangeListener( this );
+}
+
+ChartTypeTabPage::~ChartTypeTabPage()
+{
+ //delete all dialog controller
+ m_aChartTypeDialogControllerList.clear();
+
+ //delete all resource helper
+ m_pDim3DLookResourceGroup.reset();
+ m_pStackingResourceGroup.reset();
+ m_pSplineResourceGroup.reset();
+ m_pGeometryResourceGroup.reset();
+ m_pSortByXValuesResourceGroup.reset();
+ m_xSubTypeListWin.reset();
+ m_xSubTypeList.reset();
+}
+
+ChartTypeParameter ChartTypeTabPage::getCurrentParamter() const
+{
+ ChartTypeParameter aParameter;
+ aParameter.nSubTypeIndex = static_cast<sal_Int32>(m_xSubTypeList->GetSelectedItemId());
+ m_pDim3DLookResourceGroup->fillParameter( aParameter );
+ m_pStackingResourceGroup->fillParameter( aParameter );
+ m_pSplineResourceGroup->fillParameter( aParameter );
+ m_pGeometryResourceGroup->fillParameter( aParameter );
+ m_pSortByXValuesResourceGroup->fillParameter( aParameter );
+ return aParameter;
+}
+
+void ChartTypeTabPage::commitToModel( const ChartTypeParameter& rParameter )
+{
+ if( !m_pCurrentMainType )
+ return;
+
+ m_aTimerTriggeredControllerLock.startTimer();
+ m_pCurrentMainType->commitToModel( rParameter, m_xChartModel );
+}
+
+void ChartTypeTabPage::stateChanged()
+{
+ if(m_nChangingCalls)
+ return;
+ m_nChangingCalls++;
+
+ ChartTypeParameter aParameter( getCurrentParamter() );
+ if( m_pCurrentMainType )
+ {
+ m_pCurrentMainType->adjustParameterToSubType( aParameter );
+ m_pCurrentMainType->adjustSubTypeAndEnableControls( aParameter );
+ }
+ commitToModel( aParameter );
+
+ //detect the new ThreeDLookScheme
+ rtl::Reference< Diagram > xDiagram = m_xChartModel->getFirstChartDiagram();
+ // tdf#124295 - select always a 3D scheme
+ if (ThreeDLookScheme aThreeDLookScheme = xDiagram->detectScheme();
+ aThreeDLookScheme != ThreeDLookScheme::ThreeDLookScheme_Unknown)
+ aParameter.eThreeDLookScheme = aThreeDLookScheme;
+
+ try
+ {
+ xDiagram->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= aParameter.bSortByXValues;
+ }
+ catch ( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ //the controls have to be enabled/disabled accordingly
+ fillAllControls( aParameter );
+
+ m_nChangingCalls--;
+}
+
+ChartTypeDialogController* ChartTypeTabPage::getSelectedMainType()
+{
+ ChartTypeDialogController* pTypeController = nullptr;
+ auto nM = static_cast< std::vector< ChartTypeDialogController* >::size_type >(
+ m_xMainTypeList->get_selected_index() );
+ if( nM<m_aChartTypeDialogControllerList.size() )
+ pTypeController = m_aChartTypeDialogControllerList[nM].get();
+ return pTypeController;
+}
+
+IMPL_LINK_NOARG(ChartTypeTabPage, SelectSubTypeHdl, ValueSet*, void)
+{
+ if( m_pCurrentMainType )
+ {
+ ChartTypeParameter aParameter( getCurrentParamter() );
+ m_pCurrentMainType->adjustParameterToSubType( aParameter );
+ fillAllControls( aParameter, false );
+ commitToModel( aParameter );
+ }
+}
+
+IMPL_LINK_NOARG(ChartTypeTabPage, SelectMainTypeHdl, weld::TreeView&, void)
+{
+ selectMainType();
+}
+
+void ChartTypeTabPage::selectMainType()
+{
+ ChartTypeParameter aParameter( getCurrentParamter() );
+
+ if( m_pCurrentMainType )
+ {
+ m_pCurrentMainType->adjustParameterToSubType( aParameter );
+ m_pCurrentMainType->hideExtraControls();
+ }
+
+ m_pCurrentMainType = getSelectedMainType();
+ if( !m_pCurrentMainType )
+ return;
+
+ showAllControls(*m_pCurrentMainType);
+
+ m_pCurrentMainType->adjustParameterToMainType( aParameter );
+ commitToModel( aParameter );
+ //detect the new ThreeDLookScheme
+ aParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Unknown;
+ rtl::Reference< Diagram > xDiagram = m_xChartModel->getFirstChartDiagram();
+ if (xDiagram)
+ aParameter.eThreeDLookScheme = m_xChartModel->getFirstChartDiagram()->detectScheme();
+ if (!aParameter.b3DLook
+ && aParameter.eThreeDLookScheme != ThreeDLookScheme::ThreeDLookScheme_Realistic)
+ aParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Realistic;
+
+ try
+ {
+ if (xDiagram)
+ xDiagram->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= aParameter.bSortByXValues;
+ }
+ catch ( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ fillAllControls( aParameter );
+ uno::Reference< beans::XPropertySet > xTemplateProps( static_cast<cppu::OWeakObject*>(getCurrentTemplate().get()), uno::UNO_QUERY );
+ m_pCurrentMainType->fillExtraControls(m_xChartModel,xTemplateProps);
+}
+
+void ChartTypeTabPage::showAllControls( ChartTypeDialogController& rTypeController )
+{
+ m_xMainTypeList->show();
+ m_xSubTypeList->Show();
+
+ bool bShow = rTypeController.shouldShow_3DLookControl();
+ m_pDim3DLookResourceGroup->showControls( bShow );
+ bShow = rTypeController.shouldShow_StackingControl();
+ m_pStackingResourceGroup->showControls( bShow );
+ bShow = rTypeController.shouldShow_SplineControl();
+ m_pSplineResourceGroup->showControls( bShow );
+ bShow = rTypeController.shouldShow_GeometryControl();
+ m_pGeometryResourceGroup->showControls( bShow );
+ bShow = rTypeController.shouldShow_SortByXValuesResourceGroup();
+ m_pSortByXValuesResourceGroup->showControls( bShow );
+ rTypeController.showExtraControls(m_xBuilder.get());
+}
+
+void ChartTypeTabPage::fillAllControls( const ChartTypeParameter& rParameter, bool bAlsoResetSubTypeList )
+{
+ m_nChangingCalls++;
+ if( m_pCurrentMainType && bAlsoResetSubTypeList )
+ {
+ m_pCurrentMainType->fillSubTypeList(*m_xSubTypeList, rParameter);
+ }
+ m_xSubTypeList->SelectItem( static_cast<sal_uInt16>( rParameter.nSubTypeIndex) );
+ m_pDim3DLookResourceGroup->fillControls( rParameter );
+ m_pStackingResourceGroup->fillControls( rParameter );
+ m_pSplineResourceGroup->fillControls( rParameter );
+ m_pGeometryResourceGroup->fillControls( rParameter );
+ m_pSortByXValuesResourceGroup->fillControls( rParameter );
+ m_nChangingCalls--;
+}
+
+void ChartTypeTabPage::initializePage()
+{
+ if( !m_xChartModel.is() )
+ return;
+ rtl::Reference< ::chart::ChartTypeManager > xChartTypeManager = m_xChartModel->getTypeManager();
+ rtl::Reference< Diagram > xDiagram = m_xChartModel->getFirstChartDiagram();
+ Diagram::tTemplateWithServiceName aTemplate;
+ if (xDiagram)
+ aTemplate = xDiagram->getTemplate( xChartTypeManager );
+ OUString aServiceName( aTemplate.sServiceName );
+
+ bool bFound = false;
+
+ sal_uInt16 nM=0;
+ for (auto const& elem : m_aChartTypeDialogControllerList)
+ {
+ if( elem->isSubType(aServiceName) )
+ {
+ bFound = true;
+
+ m_xMainTypeList->select(nM);
+ showAllControls(*elem);
+ uno::Reference< beans::XPropertySet > xTemplateProps( static_cast<cppu::OWeakObject*>(aTemplate.xChartTypeTemplate.get()), uno::UNO_QUERY );
+ ChartTypeParameter aParameter = elem->getChartTypeParameterForService( aServiceName, xTemplateProps );
+ m_pCurrentMainType = getSelectedMainType();
+
+ //set ThreeDLookScheme
+ aParameter.eThreeDLookScheme = xDiagram->detectScheme();
+ if (!aParameter.b3DLook
+ && aParameter.eThreeDLookScheme != ThreeDLookScheme::ThreeDLookScheme_Realistic)
+ aParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Realistic;
+
+ try
+ {
+ xDiagram->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES) >>= aParameter.bSortByXValues;
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+
+ fillAllControls( aParameter );
+ if( m_pCurrentMainType )
+ m_pCurrentMainType->fillExtraControls(m_xChartModel,xTemplateProps);
+ break;
+ }
+ ++nM;
+ }
+
+ if( !bFound )
+ {
+ m_xMainTypeList->show();
+ m_xSubTypeList->Show();
+ m_pDim3DLookResourceGroup->showControls( false );
+ m_pStackingResourceGroup->showControls( false );
+ m_pSplineResourceGroup->showControls( false );
+ m_pGeometryResourceGroup->showControls( false );
+ m_pSortByXValuesResourceGroup->showControls( false );
+ }
+}
+
+bool ChartTypeTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason /*eReason*/ )
+{
+ return true; // return false if this page should not be left
+}
+
+rtl::Reference< ChartTypeTemplate > ChartTypeTabPage::getCurrentTemplate() const
+{
+ if( m_pCurrentMainType && m_xChartModel.is() )
+ {
+ ChartTypeParameter aParameter( getCurrentParamter() );
+ m_pCurrentMainType->adjustParameterToSubType( aParameter );
+ rtl::Reference< ::chart::ChartTypeManager > xChartTypeManager = m_xChartModel->getTypeManager();
+ return m_pCurrentMainType->getCurrentTemplate( aParameter, xChartTypeManager );
+ }
+ return nullptr;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_ChartType.hxx b/chart2/source/controller/dialogs/tp_ChartType.hxx
new file mode 100644
index 0000000000..c01b599f58
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_ChartType.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vector>
+
+#include <ChartTypeDialogController.hxx>
+#include <ChartTypeTemplateProvider.hxx>
+#include <TimerTriggeredControllerLock.hxx>
+
+#include <vcl/wizardmachine.hxx>
+
+namespace com::sun::star::chart2 { class XChartDocument; }
+namespace weld { class CustomWeld; }
+
+class ValueSet;
+
+namespace chart
+{
+
+class Dim3DLookResourceGroup;
+class StackingResourceGroup;
+class SplineResourceGroup;
+class GeometryResourceGroup;
+class SortByXValuesResourceGroup;
+
+class ChartTypeTabPage final : public ResourceChangeListener, public vcl::OWizardPage, public ChartTypeTemplateProvider
+{
+public:
+ ChartTypeTabPage( weld::Container* pPage, weld::DialogController* pController
+ , rtl::Reference<::chart::ChartModel> xChartModel
+ , bool bShowDescription = true );
+ virtual ~ChartTypeTabPage() override;
+
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason eReason ) override;
+
+ virtual rtl::Reference< ::chart::ChartTypeTemplate > getCurrentTemplate() const override;
+
+private:
+ ChartTypeDialogController* getSelectedMainType();
+ void showAllControls( ChartTypeDialogController& rTypeController );
+ void fillAllControls( const ChartTypeParameter& rParameter, bool bAlsoResetSubTypeList=true );
+ ChartTypeParameter getCurrentParamter() const;
+
+ virtual void stateChanged() override;
+
+ void commitToModel( const ChartTypeParameter& rParameter );
+ void selectMainType();
+
+ DECL_LINK(SelectMainTypeHdl, weld::TreeView&, void);
+ DECL_LINK(SelectSubTypeHdl, ValueSet*, void );
+
+ std::unique_ptr<Dim3DLookResourceGroup> m_pDim3DLookResourceGroup;
+ std::unique_ptr<StackingResourceGroup> m_pStackingResourceGroup;
+ std::unique_ptr<SplineResourceGroup> m_pSplineResourceGroup;
+ std::unique_ptr<GeometryResourceGroup> m_pGeometryResourceGroup;
+ std::unique_ptr<SortByXValuesResourceGroup> m_pSortByXValuesResourceGroup;
+
+ rtl::Reference<::chart::ChartModel> m_xChartModel;
+
+ std::vector< std::unique_ptr<ChartTypeDialogController> > m_aChartTypeDialogControllerList;
+ ChartTypeDialogController* m_pCurrentMainType;
+
+ sal_Int32 m_nChangingCalls;
+
+ TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
+
+ std::unique_ptr<weld::Label> m_xFT_ChooseType;
+ std::unique_ptr<weld::TreeView> m_xMainTypeList;
+ std::unique_ptr<ValueSet> m_xSubTypeList;
+ std::unique_ptr<weld::CustomWeld> m_xSubTypeListWin;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataLabel.cxx b/chart2/source/controller/dialogs/tp_DataLabel.cxx
new file mode 100644
index 0000000000..3594e3e8ff
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataLabel.cxx
@@ -0,0 +1,54 @@
+/* -*- 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 .
+ */
+
+#include "tp_DataLabel.hxx"
+
+namespace chart
+{
+
+DataLabelsTabPage::DataLabelsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_DataLabel.ui", "tp_DataLabel", &rInAttrs)
+ , m_aDataLabelResources(m_xBuilder.get(), pController->getDialog(), rInAttrs)
+{
+}
+
+std::unique_ptr<SfxTabPage> DataLabelsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<DataLabelsTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool DataLabelsTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ m_aDataLabelResources.FillItemSet(rOutAttrs);
+ return true;
+}
+
+void DataLabelsTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ m_aDataLabelResources.Reset(*rInAttrs);
+}
+
+void DataLabelsTabPage::SetNumberFormatter( SvNumberFormatter* pFormatter )
+{
+ m_aDataLabelResources.SetNumberFormatter( pFormatter );
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataLabel.hxx b/chart2/source/controller/dialogs/tp_DataLabel.hxx
new file mode 100644
index 0000000000..200063af96
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataLabel.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include "res_DataLabel.hxx"
+#include <sfx2/tabdlg.hxx>
+
+class SvNumberFormatter;
+
+namespace chart
+{
+class DataLabelsTabPage : public SfxTabPage
+{
+public:
+ DataLabelsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+
+ void SetNumberFormatter(SvNumberFormatter* pFormatter);
+
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+
+private:
+ DataLabelResources m_aDataLabelResources;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataPointOption.cxx b/chart2/source/controller/dialogs/tp_DataPointOption.cxx
new file mode 100644
index 0000000000..4c82428720
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataPointOption.cxx
@@ -0,0 +1,66 @@
+/* -*- 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 .
+ */
+
+#include "tp_DataPointOption.hxx"
+
+#include <chartview/ChartSfxItemIds.hxx>
+#include <svl/eitem.hxx>
+
+namespace chart
+{
+DataPointOptionTabPage::DataPointOptionTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_DataPointOption.ui",
+ "tp_DataPointOption", &rInAttrs)
+ , m_xCBHideLegendEntry(m_xBuilder->weld_check_button("CB_LEGEND_ENTRY_HIDDEN"))
+{
+}
+
+DataPointOptionTabPage::~DataPointOptionTabPage() {}
+
+std::unique_ptr<SfxTabPage> DataPointOptionTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<DataPointOptionTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool DataPointOptionTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ if (m_xCBHideLegendEntry->get_visible())
+ rOutAttrs->Put(
+ SfxBoolItem(SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY, m_xCBHideLegendEntry->get_active()));
+
+ return true;
+}
+
+void DataPointOptionTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ if (const SfxBoolItem* pEntryItem
+ = rInAttrs->GetItemIfSet(SCHATTR_HIDE_DATA_POINT_LEGEND_ENTRY))
+ {
+ bool bVal = pEntryItem->GetValue();
+ m_xCBHideLegendEntry->set_active(bVal);
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataPointOption.hxx b/chart2/source/controller/dialogs/tp_DataPointOption.hxx
new file mode 100644
index 0000000000..b73a8a609e
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataPointOption.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace weld
+{
+class CheckButton;
+}
+
+namespace chart
+{
+class DataPointOptionTabPage : public SfxTabPage
+{
+public:
+ DataPointOptionTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~DataPointOptionTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+
+private:
+ std::unique_ptr<weld::CheckButton> m_xCBHideLegendEntry;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataSource.cxx b/chart2/source/controller/dialogs/tp_DataSource.cxx
new file mode 100644
index 0000000000..c30ce8afae
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataSource.cxx
@@ -0,0 +1,924 @@
+/* -*- 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 .
+ */
+
+#include "tp_DataSource.hxx"
+#include <strings.hrc>
+#include <ResId.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeTemplateProvider.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <ChartModel.hxx>
+#include <RangeSelectionHelper.hxx>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <ControllerLockGuard.hxx>
+#include <DataSourceHelper.hxx>
+#include <LabeledDataSequence.hxx>
+#include "DialogModel.hxx"
+#include <o3tl/safeint.hxx>
+#include <TabPageNotifiable.hxx>
+#include <com/sun/star/chart2/XDataSeries.hpp>
+#include <com/sun/star/chart2/data/XDataProvider.hpp>
+
+#include <comphelper/diagnose_ex.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Reference;
+
+namespace
+{
+
+constexpr OUString lcl_aLabelRole( u"label"_ustr );
+
+void lcl_UpdateCurrentRange(weld::TreeView& rOutListBox, const OUString & rRole,
+ const OUString& rRange)
+{
+ int nEntry = rOutListBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ rOutListBox.set_text(nEntry, ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole), 0);
+ rOutListBox.set_text(nEntry, rRange, 1);
+ ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(rOutListBox.get_id(nEntry));
+ pEntry->m_sRole = rRole;
+ }
+}
+
+bool lcl_UpdateCurrentSeriesName(weld::TreeView& rOutListBox)
+{
+ int nEntry = rOutListBox.get_selected_index();
+ if (nEntry == -1)
+ return false;
+
+ bool bResult = false;
+ ::chart::SeriesEntry * pEntry = weld::fromId<::chart::SeriesEntry*>(rOutListBox.get_id(nEntry));
+ if (pEntry->m_xDataSeries.is() && pEntry->m_xChartType.is())
+ {
+ OUString aLabel(pEntry->m_xDataSeries->getLabelForRole(
+ pEntry->m_xChartType->getRoleOfSequenceForSeriesLabel()));
+ if (!aLabel.isEmpty())
+ {
+ rOutListBox.set_text(nEntry, aLabel);
+ bResult = true;
+ }
+ }
+ return bResult;
+}
+
+OUString lcl_GetSelectedRole(const weld::TreeView& rRoleListBox, bool bUITranslated = false)
+{
+ int nEntry = rRoleListBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ if (bUITranslated)
+ return rRoleListBox.get_text(nEntry);
+ ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(rRoleListBox.get_id(nEntry));
+ return pEntry->m_sRole;
+ }
+ return OUString();
+}
+
+OUString lcl_GetSelectedRolesRange( const weld::TreeView& rRoleListBox )
+{
+ OUString aResult;
+ int nEntry = rRoleListBox.get_selected_index();
+ if (nEntry != -1)
+ aResult = rRoleListBox.get_text(nEntry, 1);
+ return aResult;
+}
+
+OUString lcl_GetSequenceNameForLabel(const ::chart::SeriesEntry* pEntry)
+{
+ OUString aResult("values-y");
+ if (pEntry && pEntry->m_xChartType.is())
+ aResult = pEntry->m_xChartType->getRoleOfSequenceForSeriesLabel();
+ return aResult;
+}
+
+void lcl_enableRangeChoosing(bool bEnable, weld::DialogController* pDialog)
+{
+ if (!pDialog)
+ return;
+ weld::Dialog* pDlg = pDialog->getDialog();
+ pDlg->set_modal(!bEnable);
+ pDlg->set_visible(!bEnable);
+}
+
+void lcl_addLSequenceToDataSource(
+ const uno::Reference< chart2::data::XLabeledDataSequence > & xLSequence,
+ const Reference< ::chart::DataSeries > & xSource )
+{
+ if( xSource.is())
+ {
+ std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aData = xSource->getDataSequences2();
+ aData.push_back( xLSequence );
+ xSource->setData( aData );
+ }
+}
+
+uno::Reference< chart2::data::XLabeledDataSequence > lcl_findLSequenceWithOnlyLabel(
+ const rtl::Reference< ::chart::DataSeries > & xDataSource )
+{
+ uno::Reference< chart2::data::XLabeledDataSequence > xResult;
+
+ for( uno::Reference< chart2::data::XLabeledDataSequence > const & labeledDataSeq : xDataSource->getDataSequences2() )
+ {
+ // no values are set but a label exists
+ if( ! labeledDataSeq->getValues().is() &&
+ labeledDataSeq->getLabel().is())
+ {
+ xResult = labeledDataSeq;
+ break;
+ }
+ }
+
+ return xResult;
+}
+
+} // anonymous namespace
+
+namespace chart
+{
+
+DataSourceTabPage::DataSourceTabPage(weld::Container* pPage, weld::DialogController* pController,
+ DialogModel & rDialogModel,
+ ChartTypeTemplateProvider* pTemplateProvider,
+ bool bHideDescription /* = false */)
+ : ::vcl::OWizardPage(pPage, pController, "modules/schart/ui/tp_DataSource.ui", "tp_DataSource")
+ , m_pTemplateProvider(pTemplateProvider)
+ , m_rDialogModel(rDialogModel)
+ , m_pCurrentRangeChoosingField( nullptr )
+ , m_bIsDirty( false )
+ , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable*>(pController))
+ , m_xFT_CAPTION(m_xBuilder->weld_label("FT_CAPTION_FOR_WIZARD"))
+ , m_xFT_SERIES(m_xBuilder->weld_label("FT_SERIES"))
+ , m_xLB_SERIES(m_xBuilder->weld_tree_view("LB_SERIES"))
+ , m_xBTN_ADD(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBTN_REMOVE(m_xBuilder->weld_button("BTN_REMOVE"))
+ , m_xBTN_UP(m_xBuilder->weld_button("BTN_UP"))
+ , m_xBTN_DOWN(m_xBuilder->weld_button("BTN_DOWN"))
+ , m_xFT_ROLE(m_xBuilder->weld_label("FT_ROLE"))
+ , m_xLB_ROLE(m_xBuilder->weld_tree_view("LB_ROLE"))
+ , m_xFT_RANGE(m_xBuilder->weld_label("FT_RANGE"))
+ , m_xEDT_RANGE(m_xBuilder->weld_entry("EDT_RANGE"))
+ , m_xIMB_RANGE_MAIN(m_xBuilder->weld_button("IMB_RANGE_MAIN"))
+ , m_xFT_CATEGORIES(m_xBuilder->weld_label("FT_CATEGORIES"))
+ , m_xFT_DATALABELS(m_xBuilder->weld_label("FT_DATALABELS"))
+ , m_xEDT_CATEGORIES(m_xBuilder->weld_entry("EDT_CATEGORIES"))
+ , m_xIMB_RANGE_CAT(m_xBuilder->weld_button("IMB_RANGE_CAT"))
+{
+ m_xLB_SERIES->set_size_request(m_xLB_SERIES->get_approximate_digit_width() * 25,
+ m_xLB_SERIES->get_height_rows(10));
+ m_xLB_ROLE->set_size_request(m_xLB_ROLE->get_approximate_digit_width() * 60,
+ m_xLB_ROLE->get_height_rows(5));
+ m_xFT_CAPTION->set_visible(!bHideDescription);
+
+ m_aFixedTextRange = m_xFT_RANGE->get_label();
+ SetPageTitle(SchResId(STR_OBJECT_DATASERIES_PLURAL));
+
+ // set handlers
+ m_xLB_SERIES->connect_changed(LINK(this, DataSourceTabPage, SeriesSelectionChangedHdl));
+ m_xLB_ROLE->connect_changed(LINK(this, DataSourceTabPage, RoleSelectionChangedHdl));
+
+ m_xIMB_RANGE_MAIN->connect_clicked(LINK(this, DataSourceTabPage, MainRangeButtonClickedHdl));
+ m_xIMB_RANGE_CAT->connect_clicked(LINK(this, DataSourceTabPage, CategoriesRangeButtonClickedHdl));
+
+ m_xBTN_ADD->connect_clicked(LINK(this, DataSourceTabPage, AddButtonClickedHdl));
+ m_xBTN_REMOVE->connect_clicked(LINK(this, DataSourceTabPage, RemoveButtonClickedHdl));
+
+ m_xBTN_UP->connect_clicked(LINK(this, DataSourceTabPage, UpButtonClickedHdl));
+ m_xBTN_DOWN->connect_clicked(LINK(this, DataSourceTabPage, DownButtonClickedHdl));
+
+ m_xEDT_RANGE->connect_changed(LINK(this, DataSourceTabPage, RangeModifiedHdl));
+ m_xEDT_CATEGORIES->connect_changed(LINK( this, DataSourceTabPage, RangeModifiedHdl));
+
+ // init controls
+ std::vector<int> aWidths { o3tl::narrowing<int>(m_xLB_ROLE->get_approximate_digit_width() * 20) };
+ m_xLB_ROLE->set_column_fixed_widths(aWidths);
+ m_xLB_ROLE->show();
+
+ updateControlsFromDialogModel();
+
+ // select first series
+ if (m_xLB_SERIES->n_children())
+ m_xLB_SERIES->select(0);
+}
+
+void DataSourceTabPage::InsertRoleLBEntry(const OUString& rRole, const OUString& rRange)
+{
+ m_aEntries.emplace_back(new SeriesEntry);
+ SeriesEntry* pEntry = m_aEntries.back().get();
+ pEntry->m_sRole = rRole;
+ m_xLB_ROLE->append(weld::toId(pEntry),
+ ::chart::DialogModel::ConvertRoleFromInternalToUI(rRole));
+ m_xLB_ROLE->set_text(m_xLB_ROLE->n_children() - 1, rRange, 1);
+}
+
+DataSourceTabPage::~DataSourceTabPage()
+{
+}
+
+void DataSourceTabPage::Activate()
+{
+ OWizardPage::Activate();
+ updateControlsFromDialogModel();
+ m_xLB_SERIES->grab_focus();
+}
+
+void DataSourceTabPage::initializePage()
+{
+}
+
+void DataSourceTabPage::Deactivate()
+{
+ commitPage();
+ vcl::OWizardPage::Deactivate();
+}
+
+void DataSourceTabPage::commitPage()
+{
+ commitPage(::vcl::WizardTypes::eFinish);
+}
+
+bool DataSourceTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason /*eReason*/ )
+{
+ //ranges may have been edited in the meanwhile (dirty is true in that case here)
+ if( isValid() )
+ {
+ updateModelFromControl();
+ return true; //return false if this page should not be left
+ }
+ else
+ return false;
+}
+
+bool DataSourceTabPage::isRangeFieldContentValid(weld::Entry& rEdit )
+{
+ OUString aRange(rEdit.get_text());
+ bool bIsValid = aRange.isEmpty() ||
+ m_rDialogModel.getRangeSelectionHelper()->verifyCellRange(aRange);
+ rEdit.set_message_type(bIsValid ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
+ return bIsValid;
+}
+
+bool DataSourceTabPage::isValid()
+{
+ bool bRoleRangeValid = true;
+ bool bCategoriesRangeValid = true;
+ bool bHasSelectedEntry = (m_xLB_SERIES->get_selected_index() != -1);
+
+ if (bHasSelectedEntry)
+ bRoleRangeValid = isRangeFieldContentValid(*m_xEDT_RANGE);
+ if (m_xEDT_CATEGORIES->get_sensitive())
+ bCategoriesRangeValid = isRangeFieldContentValid( *m_xEDT_CATEGORIES );
+ bool bValid = ( bRoleRangeValid && bCategoriesRangeValid );
+
+ if( m_pTabPageNotifiable )
+ {
+ if( bValid )
+ m_pTabPageNotifiable->setValidPage( this );
+ else
+ m_pTabPageNotifiable->setInvalidPage( this );
+ }
+
+ return bValid;
+}
+
+void DataSourceTabPage::setDirty()
+{
+ m_bIsDirty = true;
+}
+
+void DataSourceTabPage::updateControlsFromDialogModel()
+{
+ // series
+ fillSeriesListBox();
+ SeriesSelectionChangedHdl(*m_xLB_SERIES);
+
+ // categories
+ m_xEDT_CATEGORIES->set_text(m_rDialogModel.getCategoriesRange());
+
+ updateControlState();
+}
+
+void DataSourceTabPage::fillSeriesListBox()
+{
+ rtl::Reference< DataSeries > xSelected;
+ SeriesEntry* pEntry = nullptr;
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ if (nEntry != -1)
+ {
+ pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
+ xSelected = pEntry->m_xDataSeries;
+ }
+
+ bool bHasSelectedEntry = (pEntry != nullptr);
+ int nSelectedEntry = -1;
+
+ m_xLB_SERIES->freeze();
+ m_xLB_SERIES->clear();
+
+ std::vector< DialogModel::tSeriesWithChartTypeByName > aSeries(
+ m_rDialogModel.getAllDataSeriesWithLabel() );
+
+ sal_Int32 nUnnamedSeriesIndex = 1;
+ nEntry = 0;
+ for (auto const& series : aSeries)
+ {
+ OUString aLabel(series.first);
+ if (aLabel.isEmpty())
+ {
+ if( nUnnamedSeriesIndex > 1 )
+ {
+ OUString aResString(::chart::SchResId( STR_DATA_UNNAMED_SERIES_WITH_INDEX ));
+
+ // replace index of unnamed series
+ static constexpr OUString aReplacementStr( u"%NUMBER"_ustr );
+ sal_Int32 nIndex = aResString.indexOf( aReplacementStr );
+ if( nIndex != -1 )
+ aLabel = aResString.replaceAt(
+ nIndex, aReplacementStr.getLength(),
+ OUString::number(nUnnamedSeriesIndex));
+ }
+ if( aLabel.isEmpty() )
+ aLabel = ::chart::SchResId( STR_DATA_UNNAMED_SERIES );
+
+ ++nUnnamedSeriesIndex;
+ }
+
+ m_aEntries.emplace_back(new SeriesEntry);
+ pEntry = m_aEntries.back().get();
+ pEntry->m_xDataSeries = series.second.first;
+ pEntry->m_xChartType = series.second.second;
+ m_xLB_SERIES->append(weld::toId(pEntry), aLabel);
+ if (bHasSelectedEntry && series.second.first == xSelected)
+ nSelectedEntry = nEntry;
+ ++nEntry;
+ }
+
+ m_xLB_SERIES->thaw();
+
+ if (bHasSelectedEntry && nSelectedEntry != -1)
+ m_xLB_SERIES->select(nSelectedEntry);
+}
+
+void DataSourceTabPage::fillRoleListBox()
+{
+ int nSeriesEntry = m_xLB_SERIES->get_selected_index();
+ SeriesEntry* pSeriesEntry = nullptr;
+ if (nSeriesEntry != -1)
+ pSeriesEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nSeriesEntry));
+ bool bHasSelectedEntry = (pSeriesEntry != nullptr);
+
+ int nRoleIndex = m_xLB_ROLE->get_selected_index();
+ if (!bHasSelectedEntry)
+ return;
+
+ DialogModel::tRolesWithRanges aRoles(
+ DialogModel::getRolesWithRanges(
+ pSeriesEntry->m_xDataSeries,
+ lcl_GetSequenceNameForLabel( pSeriesEntry ),
+ pSeriesEntry->m_xChartType ));
+
+ // fill role list
+ m_xLB_ROLE->freeze();
+ m_xLB_ROLE->clear();
+
+ for (auto const& elemRole : aRoles)
+ {
+ InsertRoleLBEntry(elemRole.first, elemRole.second);
+ }
+
+ m_xLB_ROLE->thaw();
+
+ // series may contain no roles, check listbox size before selecting entries
+ if (m_xLB_ROLE->n_children() > 0)
+ {
+ if (nRoleIndex == -1 || nRoleIndex >= m_xLB_ROLE->n_children())
+ nRoleIndex = 0;
+ m_xLB_ROLE->select(nRoleIndex);
+ }
+}
+
+void DataSourceTabPage::updateControlState()
+{
+ int nSeriesEntry = m_xLB_SERIES->get_selected_index();
+ bool bHasSelectedSeries = nSeriesEntry != -1;
+ bool bHasValidRole = false;
+ bool bHasRangeChooser = m_rDialogModel.getRangeSelectionHelper()->hasRangeSelection();
+
+ if( bHasSelectedSeries )
+ {
+ int nRoleEntry = m_xLB_ROLE->get_selected_index();
+ bHasValidRole = nRoleEntry != -1;
+ }
+
+ m_xBTN_ADD->set_sensitive(true);
+ m_xBTN_REMOVE->set_sensitive(bHasSelectedSeries);
+
+ m_xBTN_UP->set_sensitive(bHasSelectedSeries && (nSeriesEntry != 0));
+ m_xBTN_DOWN->set_sensitive(bHasSelectedSeries && (nSeriesEntry != m_xLB_SERIES->n_children() - 1));
+
+ bool bHasCategories = m_rDialogModel.isCategoryDiagram();
+
+ m_xFT_DATALABELS->set_visible(!bHasCategories);
+ m_xFT_CATEGORIES->set_visible( bHasCategories);
+ bool bShowIB = bHasRangeChooser;
+
+ m_xIMB_RANGE_CAT->set_visible(bShowIB);
+
+ m_xFT_ROLE->set_sensitive(bHasSelectedSeries);
+ m_xLB_ROLE->set_sensitive(bHasSelectedSeries);
+
+ m_xFT_RANGE->set_sensitive(bHasValidRole);
+ m_xEDT_RANGE->set_sensitive(bHasValidRole);
+
+ m_xFT_SERIES->set_sensitive(true);
+ m_xLB_SERIES->set_sensitive(true);
+
+ m_xIMB_RANGE_MAIN->set_visible(bShowIB);
+
+ isValid();
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, SeriesSelectionChangedHdl, weld::TreeView&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+ if (m_xLB_SERIES->get_selected_index() != -1)
+ {
+ fillRoleListBox();
+ RoleSelectionChangedHdl(*m_xLB_ROLE);
+ }
+ updateControlState();
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, RoleSelectionChangedHdl, weld::TreeView&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+ int nEntry = m_xLB_ROLE->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ OUString aSelectedRoleUI = lcl_GetSelectedRole( *m_xLB_ROLE, true );
+ OUString aSelectedRange = lcl_GetSelectedRolesRange( *m_xLB_ROLE );
+
+ // replace role in fixed text label
+ static constexpr OUString aReplacementStr( u"%VALUETYPE"_ustr );
+ sal_Int32 nIndex = m_aFixedTextRange.indexOf( aReplacementStr );
+ if( nIndex != -1 )
+ {
+ m_xFT_RANGE->set_label(
+ m_aFixedTextRange.replaceAt(
+ nIndex, aReplacementStr.getLength(), aSelectedRoleUI ));
+ }
+
+ m_xEDT_RANGE->set_text(aSelectedRange);
+ isValid();
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, MainRangeButtonClickedHdl, weld::Button&, void)
+{
+ OSL_ASSERT( m_pCurrentRangeChoosingField == nullptr );
+ m_pCurrentRangeChoosingField = m_xEDT_RANGE.get();
+ if (!m_xEDT_RANGE->get_text().isEmpty() &&
+ !updateModelFromControl( m_pCurrentRangeChoosingField))
+ return;
+
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ bool bHasSelectedEntry = (nEntry != -1);
+
+ OUString aSelectedRolesRange = lcl_GetSelectedRolesRange(*m_xLB_ROLE);
+
+ if (bHasSelectedEntry && (m_xLB_ROLE->get_selected_index() != -1))
+ {
+ OUString aUIStr(SchResId(STR_DATA_SELECT_RANGE_FOR_SERIES));
+
+ // replace role
+ OUString aReplacement( "%VALUETYPE" );
+ sal_Int32 nIndex = aUIStr.indexOf( aReplacement );
+ if( nIndex != -1 )
+ {
+ aUIStr = aUIStr.replaceAt( nIndex, aReplacement.getLength(),
+ lcl_GetSelectedRole( *m_xLB_ROLE, true ));
+ }
+ // replace series name
+ aReplacement = "%SERIESNAME";
+ nIndex = aUIStr.indexOf( aReplacement );
+ if( nIndex != -1 )
+ {
+ aUIStr = aUIStr.replaceAt(nIndex, aReplacement.getLength(),
+ m_xLB_SERIES->get_text(nEntry));
+ }
+
+ lcl_enableRangeChoosing(true, m_pDialogController);
+ m_rDialogModel.getRangeSelectionHelper()->chooseRange( aSelectedRolesRange, aUIStr, *this );
+ }
+ else
+ m_pCurrentRangeChoosingField = nullptr;
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, CategoriesRangeButtonClickedHdl, weld::Button&, void)
+{
+ OSL_ASSERT( m_pCurrentRangeChoosingField == nullptr );
+ m_pCurrentRangeChoosingField = m_xEDT_CATEGORIES.get();
+ if( !m_xEDT_CATEGORIES->get_text().isEmpty() &&
+ ! updateModelFromControl( m_pCurrentRangeChoosingField ))
+ return;
+
+ OUString aStr(SchResId(m_xFT_CATEGORIES->get_visible() ? STR_DATA_SELECT_RANGE_FOR_CATEGORIES : STR_DATA_SELECT_RANGE_FOR_DATALABELS));
+ lcl_enableRangeChoosing(true, m_pDialogController);
+ m_rDialogModel.getRangeSelectionHelper()->chooseRange(
+ m_rDialogModel.getCategoriesRange(), aStr, *this );
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, AddButtonClickedHdl, weld::Button&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ rtl::Reference< DataSeries > xSeriesToInsertAfter;
+ rtl::Reference< ChartType > xChartTypeForNewSeries;
+ if( m_pTemplateProvider )
+ m_rDialogModel.setTemplate( m_pTemplateProvider->getCurrentTemplate());
+
+ if (nEntry != -1)
+ {
+ ::chart::SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
+ xSeriesToInsertAfter = pEntry->m_xDataSeries;
+ xChartTypeForNewSeries = pEntry->m_xChartType;
+ }
+ else
+ {
+ std::vector< rtl::Reference< ChartType > > aCntVec(
+ m_rDialogModel.getAllDataSeriesContainers());
+ if( ! aCntVec.empty())
+ xChartTypeForNewSeries = aCntVec.front();
+ }
+ OSL_ENSURE( xChartTypeForNewSeries.is(), "Cannot insert new series" );
+
+ m_rDialogModel.insertSeriesAfter( xSeriesToInsertAfter, xChartTypeForNewSeries );
+ setDirty();
+
+ fillSeriesListBox();
+ // note the box was cleared and refilled, so nEntry is invalid now
+
+ int nSelEntry = m_xLB_SERIES->get_selected_index();
+ if (nSelEntry != -1)
+ {
+ ++nSelEntry;
+ if (nSelEntry < m_xLB_SERIES->n_children())
+ m_xLB_SERIES->select(nSelEntry);
+ }
+ SeriesSelectionChangedHdl(*m_xLB_SERIES);
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, RemoveButtonClickedHdl, weld::Button&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ SeriesEntry* pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
+ rtl::Reference< DataSeries > xNewSelSeries;
+ SeriesEntry * pNewSelEntry = nullptr;
+ if (nEntry + 1 < m_xLB_SERIES->n_children())
+ pNewSelEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry + 1));
+ else if (nEntry > 0)
+ pNewSelEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(nEntry - 1));
+ if (pNewSelEntry)
+ xNewSelSeries = pNewSelEntry->m_xDataSeries;
+
+ m_rDialogModel.deleteSeries( pEntry->m_xDataSeries, pEntry->m_xChartType );
+ setDirty();
+
+ m_xLB_SERIES->remove(nEntry);
+ fillSeriesListBox();
+
+ // select previous or next series
+ if (xNewSelSeries.is())
+ {
+ for (int i = 0; i < m_xLB_SERIES->n_children(); ++i)
+ {
+ pEntry = weld::fromId<::chart::SeriesEntry*>(m_xLB_SERIES->get_id(i));
+ if (pEntry->m_xDataSeries == xNewSelSeries)
+ {
+ m_xLB_SERIES->select(i);
+ break;
+ }
+ }
+ }
+ SeriesSelectionChangedHdl(*m_xLB_SERIES);
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, UpButtonClickedHdl, weld::Button&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ SeriesEntry* pEntry = nullptr;
+ if (nEntry != -1)
+ pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
+
+ bool bHasSelectedEntry = (pEntry != nullptr);
+
+ if (bHasSelectedEntry)
+ {
+ m_rDialogModel.moveSeries( pEntry->m_xDataSeries, DialogModel::MoveDirection::Up );
+ setDirty();
+ fillSeriesListBox();
+ SeriesSelectionChangedHdl(*m_xLB_SERIES);
+ }
+}
+
+IMPL_LINK_NOARG(DataSourceTabPage, DownButtonClickedHdl, weld::Button&, void)
+{
+ m_rDialogModel.startControllerLockTimer();
+
+ int nEntry = m_xLB_SERIES->get_selected_index();
+ SeriesEntry* pEntry = nullptr;
+ if (nEntry != -1)
+ pEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nEntry));
+
+ bool bHasSelectedEntry = (pEntry != nullptr);
+
+ if (bHasSelectedEntry)
+ {
+ m_rDialogModel.moveSeries( pEntry->m_xDataSeries, DialogModel::MoveDirection::Down );
+ setDirty();
+ fillSeriesListBox();
+ SeriesSelectionChangedHdl(*m_xLB_SERIES);
+ }
+}
+
+IMPL_LINK(DataSourceTabPage, RangeModifiedHdl, weld::Entry&, rEdit, void)
+{
+ // note: isValid sets the color of the edit field
+ if( isRangeFieldContentValid( rEdit ))
+ {
+ setDirty();
+ updateModelFromControl( &rEdit );
+ if (&rEdit == m_xEDT_RANGE.get())
+ {
+ if( ! lcl_UpdateCurrentSeriesName( *m_xLB_SERIES ))
+ fillSeriesListBox();
+ }
+ }
+
+ // enable/disable OK button
+ isValid();
+}
+
+void DataSourceTabPage::listeningFinished(
+ const OUString & rNewRange )
+{
+ // rNewRange becomes invalid after removing the listener
+ OUString aRange( rNewRange );
+
+ m_rDialogModel.startControllerLockTimer();
+
+ // stop listening
+ m_rDialogModel.getRangeSelectionHelper()->stopRangeListening();
+
+ // change edit field
+ if( m_pCurrentRangeChoosingField )
+ {
+ m_pCurrentRangeChoosingField->set_text(aRange);
+ m_pCurrentRangeChoosingField->grab_focus();
+ }
+
+ if (m_pCurrentRangeChoosingField == m_xEDT_RANGE.get())
+ {
+ m_xEDT_RANGE->set_text(aRange);
+ setDirty();
+ }
+ else if (m_pCurrentRangeChoosingField == m_xEDT_CATEGORIES.get())
+ {
+ m_xEDT_CATEGORIES->set_text(aRange);
+ setDirty();
+ }
+
+ updateModelFromControl(m_pCurrentRangeChoosingField);
+ if (!lcl_UpdateCurrentSeriesName(*m_xLB_SERIES))
+ fillSeriesListBox();
+
+ m_pCurrentRangeChoosingField = nullptr;
+
+ updateControlState();
+ lcl_enableRangeChoosing(false, m_pDialogController);
+}
+
+void DataSourceTabPage::disposingRangeSelection()
+{
+ m_rDialogModel.getRangeSelectionHelper()->stopRangeListening( false );
+}
+
+bool DataSourceTabPage::updateModelFromControl(const weld::Entry* pField)
+{
+ if (!m_bIsDirty)
+ return true;
+
+ ControllerLockGuardUNO aLockedControllers( m_rDialogModel.getChartModel() );
+
+ // @todo: validity check of field content
+ bool bResult = true;
+ bool bAll = (pField == nullptr);
+ Reference< data::XDataProvider > xDataProvider( m_rDialogModel.getDataProvider());
+
+ if (bAll || (pField == m_xEDT_CATEGORIES.get()))
+ {
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( m_rDialogModel.getCategories() );
+ if( xDataProvider.is())
+ {
+ OUString aRange(m_xEDT_CATEGORIES->get_text());
+ if (!aRange.isEmpty())
+ {
+ // create or change categories
+ if( !xLabeledSeq.is())
+ {
+ xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
+ m_rDialogModel.setCategories( xLabeledSeq );
+ }
+ try
+ {
+ xLabeledSeq->setValues( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
+ }
+ catch( const uno::Exception & )
+ {
+ // should work as validation should have happened before
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+ else if( xLabeledSeq.is())
+ {
+ // clear existing categories
+ xLabeledSeq.clear();
+ m_rDialogModel.setCategories( xLabeledSeq );
+ }
+ }
+ }
+
+ int nSeriesEntry = m_xLB_SERIES->get_selected_index();
+ SeriesEntry* pSeriesEntry = nullptr;
+ if (nSeriesEntry != -1)
+ pSeriesEntry = weld::fromId<SeriesEntry*>(m_xLB_SERIES->get_id(nSeriesEntry));
+ bool bHasSelectedEntry = (pSeriesEntry != nullptr);
+
+ if( bHasSelectedEntry )
+ {
+ if( bAll || (pField == m_xEDT_RANGE.get()) )
+ {
+ try
+ {
+ OUString aSelectedRole = lcl_GetSelectedRole( *m_xLB_ROLE );
+ OUString aRange(m_xEDT_RANGE->get_text());
+ OUString aSequenceRole( aSelectedRole );
+ bool bIsLabel = (aSequenceRole == lcl_aLabelRole );
+ OUString aSequenceNameForLabel( lcl_GetSequenceNameForLabel( pSeriesEntry ));
+
+ if( bIsLabel )
+ aSequenceRole = aSequenceNameForLabel;
+
+ uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSeq =
+ DataSeriesHelper::getDataSequenceByRole( pSeriesEntry->m_xDataSeries, aSequenceRole );
+
+ if( xDataProvider.is())
+ {
+ if( bIsLabel )
+ {
+ if( ! xLabeledSeq.is())
+ {
+ // check if there is already an "orphan" label sequence
+ xLabeledSeq = lcl_findLSequenceWithOnlyLabel( pSeriesEntry->m_xDataSeries );
+ if( ! xLabeledSeq.is())
+ {
+ // no corresponding labeled data sequence for label found
+ xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
+ lcl_addLSequenceToDataSource( xLabeledSeq, pSeriesEntry->m_xDataSeries );
+ }
+ }
+ if( xLabeledSeq.is())
+ {
+ if( !aRange.isEmpty())
+ {
+ Reference< data::XDataSequence > xNewSeq;
+ try
+ {
+ xNewSeq.set( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
+ }
+ catch( const uno::Exception & )
+ {
+ // should work as validation should have happened before
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ if( xNewSeq.is())
+ {
+ // update range name by the full string provided
+ // by the data provider. E.g. "a1" might become
+ // "$Sheet1.$A$1"
+ aRange = xNewSeq->getSourceRangeRepresentation();
+ Reference< beans::XPropertySet > xProp( xNewSeq, uno::UNO_QUERY_THROW );
+ xProp->setPropertyValue( "Role" , uno::Any( lcl_aLabelRole ));
+
+ //Labels should always include hidden cells, regardless of the setting chosen
+ xProp->setPropertyValue( "IncludeHiddenCells", uno::Any(true));
+ xLabeledSeq->setLabel( xNewSeq );
+ }
+ }
+ else
+ {
+ xLabeledSeq->setLabel( Reference< data::XDataSequence >());
+ }
+ }
+ }
+ else
+ {
+ if( !aRange.isEmpty())
+ {
+ Reference< data::XDataSequence > xNewSeq;
+ try
+ {
+ xNewSeq.set( xDataProvider->createDataSequenceByRangeRepresentation( aRange ));
+ }
+ catch( const uno::Exception & )
+ {
+ // should work as validation should have happened before
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ if( xNewSeq.is())
+ {
+ // update range name by the full string provided
+ // by the data provider. E.g. "a1:e1" might become
+ // "$Sheet1.$A$1:$E$1"
+ aRange = xNewSeq->getSourceRangeRepresentation();
+
+ Reference< beans::XPropertySet > xProp( xNewSeq, uno::UNO_QUERY_THROW );
+ xProp->setPropertyValue( "Role" , uno::Any( aSelectedRole ));
+ if( !xLabeledSeq.is())
+ {
+ if( aSelectedRole == aSequenceNameForLabel )
+ xLabeledSeq = lcl_findLSequenceWithOnlyLabel( pSeriesEntry->m_xDataSeries );
+ if( ! xLabeledSeq.is())
+ {
+ xLabeledSeq = DataSourceHelper::createLabeledDataSequence();
+ lcl_addLSequenceToDataSource( xLabeledSeq, pSeriesEntry->m_xDataSeries );
+ }
+ }
+ xLabeledSeq->setValues( xNewSeq );
+ }
+ }
+ }
+ }
+
+ lcl_UpdateCurrentRange( *m_xLB_ROLE, aSelectedRole, aRange );
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ bResult = false;
+ }
+ }
+ }
+
+ // update View
+ // @todo remove this when automatic view updates from calc, writer and own data sequences are available
+ if( bResult )
+ {
+ try
+ {
+ if( m_rDialogModel.getChartModel() )
+ m_rDialogModel.getChartModel()->setModified( true );
+ const DialogModelTimeBasedInfo& rInfo = m_rDialogModel.getTimeBasedInfo();
+ if(rInfo.bTimeBased)
+ {
+ m_rDialogModel.setTimeBasedRange(rInfo.bTimeBased, rInfo.nStart, rInfo.nEnd);
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_UNHANDLED_EXCEPTION("chart2");
+ }
+ }
+
+ return bResult;
+}
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataSource.hxx b/chart2/source/controller/dialogs/tp_DataSource.hxx
new file mode 100644
index 0000000000..40219d917f
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataSource.hxx
@@ -0,0 +1,149 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <DataSeries.hxx>
+#include <ChartType.hxx>
+
+#include <vcl/wizardmachine.hxx>
+
+#include <RangeSelectionListener.hxx>
+
+namespace com::sun::star::chart2 { class XChartType; }
+namespace com::sun::star::chart2 { class XDataSeries; }
+
+namespace chart { class TabPageNotifiable; }
+
+namespace chart
+{
+class ChartType;
+class ChartTypeTemplateProvider;
+class DataSeries;
+class DialogModel;
+
+class SeriesEntry
+{
+public:
+ OUString m_sRole;
+
+ /// the corresponding data series
+ rtl::Reference< ::chart::DataSeries > m_xDataSeries;
+
+ /// the chart type that contains the series (via XDataSeriesContainer)
+ rtl::Reference< ::chart::ChartType > m_xChartType;
+};
+
+class DataSourceTabPage final :
+ public ::vcl::OWizardPage,
+ public RangeSelectionListenerParent
+{
+public:
+ explicit DataSourceTabPage(weld::Container* pPage, weld::DialogController* pController,
+ DialogModel & rDialogModel,
+ ChartTypeTemplateProvider* pTemplateProvider,
+ bool bHideDescription = false);
+ virtual ~DataSourceTabPage() override;
+
+ virtual void Activate() override;
+
+ void commitPage();
+
+private:
+ // OWizardPage
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason eReason ) override;
+
+ //TabPage
+ virtual void Deactivate() override;
+
+ virtual void initializePage() override;
+
+ DECL_LINK( SeriesSelectionChangedHdl, weld::TreeView&, void );
+ DECL_LINK( RoleSelectionChangedHdl, weld::TreeView&, void );
+ DECL_LINK( MainRangeButtonClickedHdl, weld::Button&, void );
+ DECL_LINK( CategoriesRangeButtonClickedHdl, weld::Button&, void );
+ DECL_LINK( AddButtonClickedHdl, weld::Button&, void );
+ DECL_LINK( RemoveButtonClickedHdl, weld::Button&, void );
+ DECL_LINK( RangeModifiedHdl, weld::Entry&, void );
+ DECL_LINK( UpButtonClickedHdl, weld::Button&, void );
+ DECL_LINK( DownButtonClickedHdl, weld::Button&, void );
+
+ // ____ RangeSelectionListenerParent ____
+ virtual void listeningFinished( const OUString & rNewRange ) override;
+ virtual void disposingRangeSelection() override;
+
+ void InsertRoleLBEntry(const OUString& rRole, const OUString& rRange);
+
+ void updateControlState();
+
+ /** updates the internal data according to the content of the given edit
+ field. If pField is 0, all relevant fields are used
+
+ @return
+ <TRUE/> if the text from the field is a valid format to the internal
+ data was valid
+ */
+ bool updateModelFromControl(const weld::Entry* pField = nullptr);
+
+ /** @return </sal_True>, if the edit field contains a valid range entry. If no
+ XCellRangesAccess can be obtained, </sal_False> is returned.
+ */
+ bool isRangeFieldContentValid(weld::Entry& rEdit);
+
+ /** @return </sal_True>, if the tab-page is in a consistent (committable) state
+ */
+ bool isValid();
+ void setDirty();
+
+ void updateControlsFromDialogModel();
+
+ void fillSeriesListBox();
+ void fillRoleListBox();
+
+ std::vector<std::unique_ptr<SeriesEntry>> m_aEntries;
+
+ OUString m_aFixedTextRange;
+
+ ChartTypeTemplateProvider * m_pTemplateProvider;
+ DialogModel & m_rDialogModel;
+ weld::Entry* m_pCurrentRangeChoosingField;
+ bool m_bIsDirty;
+
+ TabPageNotifiable * m_pTabPageNotifiable;
+
+ std::unique_ptr<weld::Label> m_xFT_CAPTION;
+ std::unique_ptr<weld::Label> m_xFT_SERIES;
+ std::unique_ptr<weld::TreeView> m_xLB_SERIES;
+ std::unique_ptr<weld::Button> m_xBTN_ADD;
+ std::unique_ptr<weld::Button> m_xBTN_REMOVE;
+ std::unique_ptr<weld::Button> m_xBTN_UP;
+ std::unique_ptr<weld::Button> m_xBTN_DOWN;
+ std::unique_ptr<weld::Label> m_xFT_ROLE;
+ std::unique_ptr<weld::TreeView> m_xLB_ROLE;
+ std::unique_ptr<weld::Label> m_xFT_RANGE;
+ std::unique_ptr<weld::Entry> m_xEDT_RANGE;
+ std::unique_ptr<weld::Button> m_xIMB_RANGE_MAIN;
+ std::unique_ptr<weld::Label> m_xFT_CATEGORIES;
+ std::unique_ptr<weld::Label> m_xFT_DATALABELS;//used for xy charts
+ std::unique_ptr<weld::Entry> m_xEDT_CATEGORIES;
+ std::unique_ptr<weld::Button> m_xIMB_RANGE_CAT;
+};
+
+} // namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataTable.cxx b/chart2/source/controller/dialogs/tp_DataTable.cxx
new file mode 100644
index 0000000000..e6982b4a50
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataTable.cxx
@@ -0,0 +1,43 @@
+/* -*- 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/.
+ */
+
+#include "tp_DataTable.hxx"
+
+namespace chart
+{
+DataTableTabPage::DataTableTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_DataTable.ui", "DataTableTabPage",
+ &rInAttrs)
+ , m_aDataTablePropertiesResources(*m_xBuilder)
+{
+}
+
+DataTableTabPage::~DataTableTabPage() = default;
+
+std::unique_ptr<SfxTabPage> DataTableTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<DataTableTabPage>(pPage, pController, *rAttrs);
+}
+
+bool DataTableTabPage::FillItemSet(SfxItemSet* pOutAttrs)
+{
+ return m_aDataTablePropertiesResources.writeToItemSet(*pOutAttrs);
+}
+
+void DataTableTabPage::Reset(const SfxItemSet* pInAttrs)
+{
+ m_aDataTablePropertiesResources.initFromItemSet(*pInAttrs);
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_DataTable.hxx b/chart2/source/controller/dialogs/tp_DataTable.hxx
new file mode 100644
index 0000000000..00ab64cf89
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_DataTable.hxx
@@ -0,0 +1,37 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <res_DataTableProperties.hxx>
+
+namespace chart
+{
+/** Tab page for the data table properties */
+class DataTableTabPage : public SfxTabPage
+{
+private:
+ DataTablePropertiesResources m_aDataTablePropertiesResources;
+
+public:
+ DataTableTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~DataTableTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_ErrorBars.cxx b/chart2/source/controller/dialogs/tp_ErrorBars.cxx
new file mode 100644
index 0000000000..927bf1130a
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_ErrorBars.cxx
@@ -0,0 +1,67 @@
+/* -*- 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 .
+ */
+
+#include "tp_ErrorBars.hxx"
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+ErrorBarsTabPage::ErrorBarsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_ErrorBars.ui", "tp_ErrorBars", &rInAttrs)
+ , m_aErrorBarResources(m_xBuilder.get(), pController, rInAttrs, /* bNoneAvailable = */ false)
+{
+}
+
+std::unique_ptr<SfxTabPage> ErrorBarsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<ErrorBarsTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool ErrorBarsTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ m_aErrorBarResources.FillItemSet( *rOutAttrs );
+ return true;
+}
+
+void ErrorBarsTabPage::Reset( const SfxItemSet* rInAttrs )
+{
+ m_aErrorBarResources.Reset( *rInAttrs );
+}
+
+void ErrorBarsTabPage::SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth )
+{
+ m_aErrorBarResources.SetAxisMinorStepWidthForErrorBarDecimals( fMinorStepWidth );
+}
+
+void ErrorBarsTabPage::SetErrorBarType( ErrorBarResources::tErrorBarType eNewType )
+{
+ m_aErrorBarResources.SetErrorBarType( eNewType );
+}
+
+void ErrorBarsTabPage::SetChartDocumentForRangeChoosing(
+ const rtl::Reference<::chart::ChartModel> & xChartDocument )
+{
+ m_aErrorBarResources.SetChartDocumentForRangeChoosing( xChartDocument );
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_ErrorBars.hxx b/chart2/source/controller/dialogs/tp_ErrorBars.hxx
new file mode 100644
index 0000000000..159de22b0d
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_ErrorBars.hxx
@@ -0,0 +1,50 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <res_ErrorBar.hxx>
+
+#include <sfx2/tabdlg.hxx>
+#include <rtl/ref.hxx>
+
+namespace chart
+{
+class ChartModel;
+
+class ErrorBarsTabPage : public SfxTabPage
+{
+public:
+ ErrorBarsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+
+ void SetAxisMinorStepWidthForErrorBarDecimals( double fMinorStepWidth );
+ void SetErrorBarType( ErrorBarResources::tErrorBarType eNewType );
+ void SetChartDocumentForRangeChoosing(
+ const rtl::Reference<::chart::ChartModel> & xChartDocument );
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+private:
+ ErrorBarResources m_aErrorBarResources;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_LegendPosition.cxx b/chart2/source/controller/dialogs/tp_LegendPosition.cxx
new file mode 100644
index 0000000000..21a889bf85
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_LegendPosition.cxx
@@ -0,0 +1,76 @@
+/* -*- 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 .
+ */
+
+#include "tp_LegendPosition.hxx"
+#include <res_LegendPosition.hxx>
+#include <TextDirectionListBox.hxx>
+#include <chartview/ChartSfxItemIds.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+
+namespace chart
+{
+
+SchLegendPosTabPage::SchLegendPosTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_LegendPosition.ui", "tp_LegendPosition", &rInAttrs)
+ , m_aLegendPositionResources(*m_xBuilder)
+ , m_aLbTextDirection(m_xBuilder->weld_combo_box("LB_LEGEND_TEXTDIR"))
+ , m_xCBLegendNoOverlay(m_xBuilder->weld_check_button("CB_NO_OVERLAY"))
+{
+}
+
+SchLegendPosTabPage::~SchLegendPosTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SchLegendPosTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SchLegendPosTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool SchLegendPosTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ m_aLegendPositionResources.writeToItemSet(*rOutAttrs);
+
+ if (m_aLbTextDirection.get_active() != -1)
+ rOutAttrs->Put(SvxFrameDirectionItem(m_aLbTextDirection.get_active_id(), EE_PARA_WRITINGDIR));
+
+ if (m_xCBLegendNoOverlay->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_LEGEND_NO_OVERLAY, m_xCBLegendNoOverlay->get_active()));
+
+ return true;
+}
+
+void SchLegendPosTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ m_aLegendPositionResources.initFromItemSet(*rInAttrs);
+
+ if( const SvxFrameDirectionItem* pDirectionItem = rInAttrs->GetItemIfSet( EE_PARA_WRITINGDIR ) )
+ m_aLbTextDirection.set_active_id( pDirectionItem->GetValue() );
+
+ if (const SfxBoolItem* pNoOverlayItem = rInAttrs->GetItemIfSet(SCHATTR_LEGEND_NO_OVERLAY))
+ {
+ bool bVal = pNoOverlayItem->GetValue();
+ m_xCBLegendNoOverlay->set_active(bVal);
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_LegendPosition.hxx b/chart2/source/controller/dialogs/tp_LegendPosition.hxx
new file mode 100644
index 0000000000..7a444694c3
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_LegendPosition.hxx
@@ -0,0 +1,49 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+#include <res_LegendPosition.hxx>
+#include <TextDirectionListBox.hxx>
+#include <optional>
+
+namespace chart
+{
+
+class SchLegendPosTabPage : public SfxTabPage
+{
+private:
+
+ LegendPositionResources m_aLegendPositionResources;
+ TextDirectionListBox m_aLbTextDirection;
+ std::unique_ptr<weld::CheckButton> m_xCBLegendNoOverlay;
+
+public:
+ SchLegendPosTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SchLegendPosTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_PointGeometry.cxx b/chart2/source/controller/dialogs/tp_PointGeometry.cxx
new file mode 100644
index 0000000000..7c2c4d942e
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_PointGeometry.cxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+
+#include "tp_PointGeometry.hxx"
+#include <res_BarGeometry.hxx>
+
+#include <chartview/ChartSfxItemIds.hxx>
+
+#include <svl/intitem.hxx>
+#include <svx/svx3ditems.hxx>
+
+namespace chart
+{
+
+SchLayoutTabPage::SchLayoutTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_ChartType.ui", "tp_ChartType", &rInAttrs)
+{
+ m_pGeometryResources.reset(new BarGeometryResources(m_xBuilder.get()));
+}
+
+SchLayoutTabPage::~SchLayoutTabPage()
+{
+ m_pGeometryResources.reset();
+}
+
+std::unique_ptr<SfxTabPage> SchLayoutTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SchLayoutTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool SchLayoutTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ int nShape = m_pGeometryResources ? m_pGeometryResources->get_selected_index() : -1;
+ if (nShape != -1)
+ {
+ tools::Long nSegs=32;
+
+ if (nShape==CHART_SHAPE3D_PYRAMID)
+ nSegs=4;
+
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_STYLE_SHAPE,nShape));
+ rOutAttrs->Put(makeSvx3DHorizontalSegmentsItem(nSegs));
+ }
+ return true;
+}
+
+void SchLayoutTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ if (const SfxInt32Item* pShapeItem = rInAttrs->GetItemIfSet(SCHATTR_STYLE_SHAPE))
+ {
+ tools::Long nVal = pShapeItem->GetValue();
+ if(m_pGeometryResources)
+ {
+ m_pGeometryResources->select(static_cast<sal_uInt16>(nVal));
+ m_pGeometryResources->set_visible(true);
+ }
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_PointGeometry.hxx b/chart2/source/controller/dialogs/tp_PointGeometry.hxx
new file mode 100644
index 0000000000..326cc90259
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_PointGeometry.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace chart
+{
+class BarGeometryResources;
+class SchLayoutTabPage : public SfxTabPage
+{
+public:
+ SchLayoutTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs);
+ virtual ~SchLayoutTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+
+private:
+ std::unique_ptr<BarGeometryResources> m_pGeometryResources;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_PolarOptions.cxx b/chart2/source/controller/dialogs/tp_PolarOptions.cxx
new file mode 100644
index 0000000000..ad7b2b6f0f
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_PolarOptions.cxx
@@ -0,0 +1,106 @@
+/* -*- 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 .
+ */
+
+#include "tp_PolarOptions.hxx"
+#include <chartview/ChartSfxItemIds.hxx>
+
+#include <svl/eitem.hxx>
+#include <svx/sdangitm.hxx>
+#include <officecfg/Office/Compatibility.hxx>
+
+namespace chart
+{
+
+PolarOptionsTabPage::PolarOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_PolarOptions.ui", "tp_PolarOptions", &rInAttrs)
+ , m_xCB_Clockwise(m_xBuilder->weld_check_button("CB_CLOCKWISE"))
+ , m_xFL_StartingAngle(m_xBuilder->weld_frame("frameANGLE"))
+ , m_xNF_StartingAngle(m_xBuilder->weld_metric_spin_button("NF_STARTING_ANGLE", FieldUnit::DEGREE))
+ , m_xFL_PlotOptions(m_xBuilder->weld_frame("framePLOT_OPTIONS"))
+ , m_xCB_IncludeHiddenCells(m_xBuilder->weld_check_button("CB_INCLUDE_HIDDEN_CELLS_POLAR"))
+ , m_xAngleDial(new svx::DialControl)
+ , m_xAngleDialWin(new weld::CustomWeld(*m_xBuilder, "CT_ANGLE_DIAL", *m_xAngleDial))
+{
+ m_xAngleDial->SetLinkedField(m_xNF_StartingAngle.get());
+}
+
+PolarOptionsTabPage::~PolarOptionsTabPage()
+{
+ m_xAngleDialWin.reset();
+ m_xAngleDial.reset();
+}
+
+std::unique_ptr<SfxTabPage> PolarOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<PolarOptionsTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool PolarOptionsTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ if (m_xAngleDialWin->get_visible())
+ {
+ rOutAttrs->Put(SdrAngleItem(SCHATTR_STARTING_ANGLE, m_xAngleDial->GetRotation()));
+ }
+
+ if( m_xCB_Clockwise->get_visible() )
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_CLOCKWISE,m_xCB_Clockwise->get_active()));
+
+ if (m_xCB_IncludeHiddenCells->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_INCLUDE_HIDDEN_CELLS, m_xCB_IncludeHiddenCells->get_active()));
+
+ return true;
+}
+
+void PolarOptionsTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ if (const SdrAngleItem* pAngleItem = rInAttrs->GetItemIfSet(SCHATTR_STARTING_ANGLE))
+ {
+ Degree100 nTmp = pAngleItem->GetValue();
+ m_xAngleDial->SetRotation( nTmp );
+ }
+ else
+ {
+ m_xFL_StartingAngle->hide();
+ }
+ // tdf#108059 Hide clockwise orientation checkbox in OOXML-heavy environments it would be useless anyways
+ const SfxBoolItem* pClockWiseItem = nullptr;
+ if (!officecfg::Office::Compatibility::View::ClockwisePieChartDirection::get() &&
+ (pClockWiseItem = rInAttrs->GetItemIfSet(SCHATTR_CLOCKWISE)))
+ {
+ bool bCheck = pClockWiseItem->GetValue();
+ m_xCB_Clockwise->set_active(bCheck);
+ }
+ else
+ {
+ m_xCB_Clockwise->hide();
+ }
+ if (const SfxBoolItem* pHiddenCellsItem = rInAttrs->GetItemIfSet(SCHATTR_INCLUDE_HIDDEN_CELLS))
+ {
+ bool bVal = pHiddenCellsItem->GetValue();
+ m_xCB_IncludeHiddenCells->set_active(bVal);
+ }
+ else
+ {
+ m_xFL_PlotOptions->hide();
+ }
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_PolarOptions.hxx b/chart2/source/controller/dialogs/tp_PolarOptions.hxx
new file mode 100644
index 0000000000..eba4018052
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_PolarOptions.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/dialcontrol.hxx>
+
+namespace weld {
+ class CheckButton;
+ class CustomWeld;
+ class Frame;
+ class SpinButton;
+}
+
+namespace chart
+{
+
+class PolarOptionsTabPage : public SfxTabPage
+{
+
+public:
+ PolarOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~PolarOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+
+private:
+ std::unique_ptr<weld::CheckButton> m_xCB_Clockwise;
+ std::unique_ptr<weld::Frame> m_xFL_StartingAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xNF_StartingAngle;
+ std::unique_ptr<weld::Frame> m_xFL_PlotOptions;
+ std::unique_ptr<weld::CheckButton> m_xCB_IncludeHiddenCells;
+ std::unique_ptr<svx::DialControl> m_xAngleDial;
+ std::unique_ptr<weld::CustomWeld> m_xAngleDialWin;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_RangeChooser.cxx b/chart2/source/controller/dialogs/tp_RangeChooser.cxx
new file mode 100644
index 0000000000..a88f6a826e
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_RangeChooser.cxx
@@ -0,0 +1,380 @@
+/* -*- 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 .
+ */
+
+#include "tp_RangeChooser.hxx"
+#include <DataSourceHelper.hxx>
+#include <ChartTypeTemplateProvider.hxx>
+#include <ChartTypeTemplate.hxx>
+#include "DialogModel.hxx"
+#include <RangeSelectionHelper.hxx>
+#include <TabPageNotifiable.hxx>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <officecfg/Office/Common.hxx>
+#include <osl/diagnose.h>
+
+namespace
+{
+ void lcl_ShowChooserButton(
+ weld::Button& rChooserButton,
+ bool bShow)
+ {
+ if( rChooserButton.get_visible() != bShow )
+ {
+ rChooserButton.set_visible( bShow );
+ }
+ }
+
+ void lcl_enableRangeChoosing(bool bEnable, weld::DialogController* pDialog)
+ {
+ if (!pDialog)
+ return;
+ weld::Dialog* pDlg = pDialog->getDialog();
+ pDlg->set_modal(!bEnable);
+ pDlg->set_visible(!bEnable);
+ }
+
+} // anonymous namespace
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+using ::com::sun::star::uno::Sequence;
+
+RangeChooserTabPage::RangeChooserTabPage(weld::Container* pPage, weld::DialogController* pController, DialogModel & rDialogModel,
+ ChartTypeTemplateProvider* pTemplateProvider,
+ bool bHideDescription /* = false */)
+ : OWizardPage(pPage, pController, "modules/schart/ui/tp_RangeChooser.ui", "tp_RangeChooser")
+ , m_nChangingControlCalls(0)
+ , m_bIsDirty(false)
+ , m_pTemplateProvider(pTemplateProvider)
+ , m_rDialogModel( rDialogModel )
+ , m_pTabPageNotifiable(dynamic_cast<TabPageNotifiable*>(pController))
+ , m_xFT_Caption(m_xBuilder->weld_label("FT_CAPTION_FOR_WIZARD"))
+ , m_xED_Range(m_xBuilder->weld_entry("ED_RANGE"))
+ , m_xIB_Range(m_xBuilder->weld_button("IB_RANGE"))
+ , m_xRB_Rows(m_xBuilder->weld_radio_button("RB_DATAROWS"))
+ , m_xRB_Columns(m_xBuilder->weld_radio_button("RB_DATACOLS"))
+ , m_xCB_FirstRowAsLabel(m_xBuilder->weld_check_button("CB_FIRST_ROW_ASLABELS"))
+ , m_xCB_FirstColumnAsLabel(m_xBuilder->weld_check_button("CB_FIRST_COLUMN_ASLABELS"))
+ , m_xFTTitle(m_xBuilder->weld_label("STR_PAGE_DATA_RANGE"))
+ , m_xFL_TimeBased(m_xBuilder->weld_widget("separator1"))
+ , m_xCB_TimeBased(m_xBuilder->weld_check_button("CB_TIME_BASED"))
+ , m_xFT_TimeStart(m_xBuilder->weld_label("label1"))
+ , m_xEd_TimeStart(m_xBuilder->weld_entry("ED_TIME_BASED_START"))
+ , m_xFT_TimeEnd(m_xBuilder->weld_label("label2"))
+ , m_xEd_TimeEnd(m_xBuilder->weld_entry("ED_TIME_BASED_END"))
+{
+ m_xFT_Caption->set_visible(!bHideDescription);
+
+ SetPageTitle(m_xFTTitle->get_label());// OH:remove later with dialog
+
+ // set defaults as long as DetectArguments does not work
+ m_xRB_Columns->set_active(true);
+ m_xCB_FirstColumnAsLabel->set_active(true);
+ m_xCB_FirstRowAsLabel->set_active(true);
+
+ // BM: Note, that the range selection is not available, if there is no view.
+ // This happens for charts having their own embedded spreadsheet. If you
+ // force to get the range selection here, this would mean when entering this
+ // page the calc view would be created in this case. So, I enable the
+ // button here, and in the worst case nothing happens when it is pressed.
+ // Not nice, but I see no better solution for the moment.
+ m_xIB_Range->connect_clicked( LINK( this, RangeChooserTabPage, ChooseRangeHdl ));
+
+ m_xED_Range->connect_changed( LINK( this, RangeChooserTabPage, ControlEditedHdl ));
+ m_xRB_Rows->connect_toggled( LINK( this, RangeChooserTabPage, ControlChangedRadioHdl ) );
+ m_xCB_FirstRowAsLabel->connect_toggled( LINK( this, RangeChooserTabPage, ControlChangedCheckBoxHdl ) );
+ m_xCB_FirstColumnAsLabel->connect_toggled( LINK( this, RangeChooserTabPage, ControlChangedCheckBoxHdl ) );
+ m_xCB_TimeBased->connect_toggled( LINK( this, RangeChooserTabPage, ControlChangedCheckBoxHdl ) );
+ m_xEd_TimeStart->connect_changed( LINK( this, RangeChooserTabPage, ControlChangedHdl ) );
+ m_xEd_TimeEnd->connect_changed( LINK( this, RangeChooserTabPage, ControlChangedHdl ) );
+
+ if ( !officecfg::Office::Common::Misc::ExperimentalMode::get() )
+ {
+ m_xFL_TimeBased->hide();
+ m_xCB_TimeBased->hide();
+ m_xFT_TimeStart->hide();
+ m_xEd_TimeStart->hide();
+ m_xFT_TimeEnd->hide();
+ m_xEd_TimeEnd->hide();
+ }
+}
+
+RangeChooserTabPage::~RangeChooserTabPage()
+{
+}
+
+void RangeChooserTabPage::Activate()
+{
+ OWizardPage::Activate();
+ initControlsFromModel();
+ m_xED_Range->grab_focus();
+}
+
+void RangeChooserTabPage::initControlsFromModel()
+{
+ m_nChangingControlCalls++;
+
+ if(m_pTemplateProvider)
+ m_xCurrentChartTypeTemplate = m_pTemplateProvider->getCurrentTemplate();
+
+ bool bUseColumns = !m_xRB_Rows->get_active();
+ bool bFirstCellAsLabel = bUseColumns ? m_xCB_FirstRowAsLabel->get_active() : m_xCB_FirstColumnAsLabel->get_active();
+ bool bHasCategories = bUseColumns ? m_xCB_FirstColumnAsLabel->get_active() : m_xCB_FirstRowAsLabel->get_active();
+
+ bool bIsValid = m_rDialogModel.allArgumentsForRectRangeDetected();
+ if( bIsValid )
+ m_rDialogModel.detectArguments(m_aLastValidRangeString, bUseColumns, bFirstCellAsLabel, bHasCategories );
+ else
+ m_aLastValidRangeString.clear();
+
+ m_xED_Range->set_text( m_aLastValidRangeString );
+
+ m_xRB_Rows->set_active( !bUseColumns );
+ m_xRB_Columns->set_active( bUseColumns );
+
+ m_xCB_FirstRowAsLabel->set_active( m_xRB_Rows->get_active()?bHasCategories:bFirstCellAsLabel );
+ m_xCB_FirstColumnAsLabel->set_active( m_xRB_Columns->get_active()?bHasCategories:bFirstCellAsLabel );
+
+ isValid();
+
+ m_nChangingControlCalls--;
+}
+
+void RangeChooserTabPage::Deactivate()
+{
+ commitPage();
+ vcl::OWizardPage::Deactivate();
+}
+
+void RangeChooserTabPage::commitPage()
+{
+ commitPage(::vcl::WizardTypes::eFinish);
+}
+
+bool RangeChooserTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason /*eReason*/ )
+{
+ //ranges may have been edited in the meanwhile (dirty is true in that case here)
+ if( isValid() )
+ {
+ changeDialogModelAccordingToControls();
+ return true; // return false if this page should not be left
+ }
+ else
+ return false;
+}
+
+void RangeChooserTabPage::changeDialogModelAccordingToControls()
+{
+ if(m_nChangingControlCalls>0)
+ return;
+
+ if( !m_xCurrentChartTypeTemplate.is() )
+ {
+ if(m_pTemplateProvider)
+ m_xCurrentChartTypeTemplate = m_pTemplateProvider->getCurrentTemplate();
+ if( !m_xCurrentChartTypeTemplate.is())
+ {
+ OSL_FAIL( "Need a template to change data source" );
+ return;
+ }
+ }
+
+ if( !m_bIsDirty )
+ return;
+
+ bool bFirstCellAsLabel = ( m_xCB_FirstColumnAsLabel->get_active() && !m_xRB_Columns->get_active() )
+ || ( m_xCB_FirstRowAsLabel->get_active() && !m_xRB_Rows->get_active() );
+ bool bHasCategories = ( m_xCB_FirstColumnAsLabel->get_active() && m_xRB_Columns->get_active() )
+ || ( m_xCB_FirstRowAsLabel->get_active() && m_xRB_Rows->get_active() );
+ bool bTimeBased = m_xCB_TimeBased->get_active();
+
+ Sequence< beans::PropertyValue > aArguments(
+ DataSourceHelper::createArguments(
+ m_xRB_Columns->get_active(), bFirstCellAsLabel, bHasCategories ) );
+
+ if(bTimeBased)
+ {
+ aArguments.realloc( aArguments.getLength() + 1 );
+ aArguments.getArray()[aArguments.getLength() - 1] =
+ beans::PropertyValue( "TimeBased", -1, uno::Any(bTimeBased),
+ beans::PropertyState_DIRECT_VALUE );
+ }
+
+ // only if range is valid
+ if( m_aLastValidRangeString != m_xED_Range->get_text())
+ return;
+
+ m_rDialogModel.setTemplate( m_xCurrentChartTypeTemplate );
+ aArguments.realloc( aArguments.getLength() + 1 );
+ aArguments.getArray()[aArguments.getLength() - 1] =
+ beans::PropertyValue( "CellRangeRepresentation" , -1,
+ uno::Any( m_aLastValidRangeString ),
+ beans::PropertyState_DIRECT_VALUE );
+ m_rDialogModel.setData( aArguments );
+ m_bIsDirty = false;
+
+ if(bTimeBased)
+ {
+ sal_Int32 nStart = m_xEd_TimeStart->get_text().toInt32();
+ sal_Int32 nEnd = m_xEd_TimeEnd->get_text().toInt32();
+ m_rDialogModel.setTimeBasedRange(true, nStart, nEnd);
+ }
+
+ //@todo warn user that the selected range is not valid
+ //@todo better: disable OK-Button if range is invalid
+}
+
+bool RangeChooserTabPage::isValid()
+{
+ OUString aRange( m_xED_Range->get_text());
+ bool bFirstCellAsLabel = ( m_xCB_FirstColumnAsLabel->get_active() && !m_xRB_Columns->get_active() )
+ || ( m_xCB_FirstRowAsLabel->get_active() && !m_xRB_Rows->get_active() );
+ bool bHasCategories = ( m_xCB_FirstColumnAsLabel->get_active() && m_xRB_Columns->get_active() )
+ || ( m_xCB_FirstRowAsLabel->get_active() && m_xRB_Rows->get_active() );
+ bool bIsValid = ( aRange.isEmpty() ) ||
+ m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
+ DataSourceHelper::createArguments(
+ aRange, Sequence< sal_Int32 >(), m_xRB_Columns->get_active(), bFirstCellAsLabel, bHasCategories ));
+
+ if( bIsValid )
+ {
+ m_xED_Range->set_message_type(weld::EntryMessageType::Normal);
+ if( m_pTabPageNotifiable )
+ m_pTabPageNotifiable->setValidPage( this );
+ m_aLastValidRangeString = aRange;
+ }
+ else
+ {
+ m_xED_Range->set_message_type(weld::EntryMessageType::Error);
+ if( m_pTabPageNotifiable )
+ m_pTabPageNotifiable->setInvalidPage( this );
+ }
+
+ // enable/disable controls
+ // #i79531# if the range is valid but an action of one of these buttons
+ // would render it invalid, the button should be disabled
+ if( bIsValid )
+ {
+ bool bDataInColumns = m_xRB_Columns->get_active();
+ bool bIsSwappedRangeValid = m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
+ DataSourceHelper::createArguments(
+ aRange, Sequence< sal_Int32 >(), ! bDataInColumns, bHasCategories, bFirstCellAsLabel ));
+ m_xRB_Rows->set_sensitive( bIsSwappedRangeValid );
+ m_xRB_Columns->set_sensitive( bIsSwappedRangeValid );
+
+ m_xCB_FirstRowAsLabel->set_sensitive(
+ m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
+ DataSourceHelper::createArguments(
+ aRange, Sequence< sal_Int32 >(), m_xRB_Columns->get_active(),
+ bDataInColumns ? ! bFirstCellAsLabel : bFirstCellAsLabel,
+ bDataInColumns ? bHasCategories : ! bHasCategories )));
+ m_xCB_FirstColumnAsLabel->set_sensitive(
+ m_rDialogModel.getRangeSelectionHelper()->verifyArguments(
+ DataSourceHelper::createArguments(
+ aRange, Sequence< sal_Int32 >(), m_xRB_Columns->get_active(),
+ bDataInColumns ? bFirstCellAsLabel : ! bFirstCellAsLabel,
+ bDataInColumns ? ! bHasCategories : bHasCategories )));
+ }
+ else
+ {
+ m_xRB_Rows->set_sensitive( bIsValid );
+ m_xRB_Columns->set_sensitive( bIsValid );
+ m_xCB_FirstRowAsLabel->set_sensitive( bIsValid );
+ m_xCB_FirstColumnAsLabel->set_sensitive( bIsValid );
+ }
+
+ bool bShowIB = m_rDialogModel.getRangeSelectionHelper()->hasRangeSelection();
+ lcl_ShowChooserButton( *m_xIB_Range, bShowIB );
+
+ return bIsValid;
+}
+
+IMPL_LINK_NOARG(RangeChooserTabPage, ControlEditedHdl, weld::Entry&, void)
+{
+ setDirty();
+ isValid();
+}
+
+IMPL_LINK_NOARG(RangeChooserTabPage, ControlChangedRadioHdl, weld::Toggleable&, void)
+{
+ ControlChangedHdl(*m_xED_Range);
+}
+
+IMPL_LINK_NOARG(RangeChooserTabPage, ControlChangedCheckBoxHdl, weld::Toggleable&, void)
+{
+ ControlChangedHdl(*m_xED_Range);
+}
+
+IMPL_LINK_NOARG(RangeChooserTabPage, ControlChangedHdl, weld::Entry&, void)
+{
+ setDirty();
+ if( isValid())
+ changeDialogModelAccordingToControls();
+}
+
+IMPL_LINK_NOARG(RangeChooserTabPage, ChooseRangeHdl, weld::Button&, void)
+{
+ OUString aRange = m_xED_Range->get_text();
+ OUString aTitle = m_xFTTitle->get_label();
+
+ lcl_enableRangeChoosing(true, m_pDialogController);
+ m_rDialogModel.getRangeSelectionHelper()->chooseRange( aRange, aTitle, *this );
+}
+
+void RangeChooserTabPage::listeningFinished( const OUString & rNewRange )
+{
+ //user has selected a new range
+
+ // rNewRange becomes invalid after removing the listener
+ OUString aRange( rNewRange );
+
+ m_rDialogModel.startControllerLockTimer();
+
+ // stop listening
+ m_rDialogModel.getRangeSelectionHelper()->stopRangeListening();
+
+ //update dialog state
+ m_xED_Range->set_text(aRange);
+ m_xED_Range->grab_focus();
+
+ setDirty();
+ if( isValid())
+ changeDialogModelAccordingToControls();
+
+ lcl_enableRangeChoosing(false, m_pDialogController);
+}
+
+void RangeChooserTabPage::disposingRangeSelection()
+{
+ m_rDialogModel.getRangeSelectionHelper()->stopRangeListening( false );
+}
+
+void RangeChooserTabPage::setDirty()
+{
+ if( m_nChangingControlCalls == 0 )
+ m_bIsDirty = true;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_RangeChooser.hxx b/chart2/source/controller/dialogs/tp_RangeChooser.hxx
new file mode 100644
index 0000000000..428e8a127d
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_RangeChooser.hxx
@@ -0,0 +1,98 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <RangeSelectionListener.hxx>
+
+#include <vcl/wizardmachine.hxx>
+
+namespace chart { class TabPageNotifiable; }
+
+namespace chart
+{
+class ChartTypeTemplate;
+class ChartTypeTemplateProvider;
+class DialogModel;
+
+class RangeChooserTabPage final : public vcl::OWizardPage, public RangeSelectionListenerParent
+{
+public:
+
+ RangeChooserTabPage(weld::Container* pPage, weld::DialogController* pController, DialogModel & rDialogModel,
+ ChartTypeTemplateProvider* pTemplateProvider,
+ bool bHideDescription = false);
+ virtual ~RangeChooserTabPage() override;
+
+ //RangeSelectionListenerParent
+ virtual void listeningFinished( const OUString & rNewRange ) override;
+ virtual void disposingRangeSelection() override;
+
+ virtual void Activate() override;
+
+ void commitPage();
+
+private:
+
+ //OWizardPage
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason eReason ) override;
+
+ //TabPage
+ virtual void Deactivate() override;
+
+ void initControlsFromModel();
+ void changeDialogModelAccordingToControls();
+ bool isValid();
+ void setDirty();
+
+ DECL_LINK( ChooseRangeHdl, weld::Button&, void );
+ DECL_LINK( ControlChangedHdl, weld::Entry&, void );
+ DECL_LINK( ControlChangedCheckBoxHdl, weld::Toggleable&, void );
+ DECL_LINK( ControlChangedRadioHdl, weld::Toggleable&, void );
+ DECL_LINK( ControlEditedHdl, weld::Entry&, void );
+
+ sal_Int32 m_nChangingControlCalls;
+ bool m_bIsDirty;
+
+ OUString m_aLastValidRangeString;
+ rtl::Reference< ::chart::ChartTypeTemplate > m_xCurrentChartTypeTemplate;
+ ChartTypeTemplateProvider* m_pTemplateProvider;
+
+ DialogModel & m_rDialogModel;
+ TabPageNotifiable * m_pTabPageNotifiable;
+
+ std::unique_ptr<weld::Label> m_xFT_Caption;
+ std::unique_ptr<weld::Entry> m_xED_Range;
+ std::unique_ptr<weld::Button> m_xIB_Range;
+ std::unique_ptr<weld::RadioButton> m_xRB_Rows;
+ std::unique_ptr<weld::RadioButton> m_xRB_Columns;
+ std::unique_ptr<weld::CheckButton> m_xCB_FirstRowAsLabel;
+ std::unique_ptr<weld::CheckButton> m_xCB_FirstColumnAsLabel;
+ std::unique_ptr<weld::Label> m_xFTTitle;
+ std::unique_ptr<weld::Widget> m_xFL_TimeBased;
+ std::unique_ptr<weld::CheckButton> m_xCB_TimeBased;
+ std::unique_ptr<weld::Label> m_xFT_TimeStart;
+ std::unique_ptr<weld::Entry> m_xEd_TimeStart;
+ std::unique_ptr<weld::Label> m_xFT_TimeEnd;
+ std::unique_ptr<weld::Entry> m_xEd_TimeEnd;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Scale.cxx b/chart2/source/controller/dialogs/tp_Scale.cxx
new file mode 100644
index 0000000000..b8c9f05983
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Scale.cxx
@@ -0,0 +1,637 @@
+/* -*- 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 .
+ */
+
+#include "tp_Scale.hxx"
+
+#include <ResId.hxx>
+#include <strings.hrc>
+#include <chartview/ChartSfxItemIds.hxx>
+#include <AxisHelper.hxx>
+
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+#include <sfx2/dialoghelper.hxx>
+#include <svx/chrtitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/numformat.hxx>
+#include <vcl/formatter.hxx>
+#include <vcl/weld.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/chart2/AxisType.hpp>
+
+using namespace ::com::sun::star;
+
+namespace chart
+{
+
+namespace
+{
+
+void lcl_setValue(weld::FormattedSpinButton& rFmtField, double fValue)
+{
+ rFmtField.GetFormatter().SetValue(fValue);
+}
+
+}
+
+ScaleTabPage::ScaleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_Scale.ui", "tp_Scale", &rInAttrs)
+ , fMin(0.0)
+ , fMax(0.0)
+ , fStepMain(0.0)
+ , nStepHelp(0)
+ , fOrigin(0.0)
+ , m_nTimeResolution(1)
+ , m_nMainTimeUnit(1)
+ , m_nHelpTimeUnit(1)
+ , m_nAxisType(chart2::AxisType::REALNUMBER)
+ , m_bAllowDateAxis(false)
+ , pNumFormatter(nullptr)
+ , m_bShowAxisOrigin(false)
+ , m_xCbxReverse(m_xBuilder->weld_check_button("CBX_REVERSE"))
+ , m_xCbxLogarithm(m_xBuilder->weld_check_button("CBX_LOGARITHM"))
+ , m_xBxType(m_xBuilder->weld_widget("boxTYPE"))
+ , m_xLB_AxisType(m_xBuilder->weld_combo_box("LB_AXIS_TYPE"))
+ , m_xBxMinMax(m_xBuilder->weld_widget("gridMINMAX"))
+ , m_xFmtFldMin(m_xBuilder->weld_formatted_spin_button("EDT_MIN"))
+ , m_xCbxAutoMin(m_xBuilder->weld_check_button("CBX_AUTO_MIN"))
+ , m_xFmtFldMax(m_xBuilder->weld_formatted_spin_button("EDT_MAX"))
+ , m_xCbxAutoMax(m_xBuilder->weld_check_button("CBX_AUTO_MAX"))
+ , m_xBxResolution(m_xBuilder->weld_widget("boxRESOLUTION"))
+ , m_xLB_TimeResolution(m_xBuilder->weld_combo_box("LB_TIME_RESOLUTION"))
+ , m_xCbx_AutoTimeResolution(m_xBuilder->weld_check_button("CBX_AUTO_TIME_RESOLUTION"))
+ , m_xTxtMain(m_xBuilder->weld_label("TXT_STEP_MAIN"))
+ , m_xFmtFldStepMain(m_xBuilder->weld_formatted_spin_button("EDT_STEP_MAIN"))
+ , m_xMt_MainDateStep(m_xBuilder->weld_spin_button("MT_MAIN_DATE_STEP"))
+ , m_xLB_MainTimeUnit(m_xBuilder->weld_combo_box("LB_MAIN_TIME_UNIT"))
+ , m_xCbxAutoStepMain(m_xBuilder->weld_check_button("CBX_AUTO_STEP_MAIN"))
+ , m_xTxtHelpCount(m_xBuilder->weld_label("TXT_STEP_HELP_COUNT"))
+ , m_xTxtHelp(m_xBuilder->weld_label("TXT_STEP_HELP"))
+ , m_xMtStepHelp(m_xBuilder->weld_spin_button("MT_STEPHELP"))
+ , m_xLB_HelpTimeUnit(m_xBuilder->weld_combo_box("LB_HELP_TIME_UNIT"))
+ , m_xCbxAutoStepHelp(m_xBuilder->weld_check_button("CBX_AUTO_STEP_HELP"))
+ , m_xFmtFldOrigin(m_xBuilder->weld_formatted_spin_button("EDT_ORIGIN"))
+ , m_xCbxAutoOrigin(m_xBuilder->weld_check_button("CBX_AUTO_ORIGIN"))
+ , m_xBxOrigin(m_xBuilder->weld_widget("boxORIGIN"))
+{
+ m_xCbxAutoMin->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+ m_xCbxAutoMax->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+ m_xCbxAutoStepMain->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+ m_xCbxAutoStepHelp->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+ m_xCbxAutoOrigin->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+ m_xCbx_AutoTimeResolution->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl));
+
+ Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter();
+ rFmtFldMax.ClearMinValue();
+ rFmtFldMax.ClearMaxValue();
+ Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter();
+ rFmtFldMin.ClearMinValue();
+ rFmtFldMin.ClearMaxValue();
+ Formatter& rFmtFldStepMain = m_xFmtFldStepMain->GetFormatter();
+ rFmtFldStepMain.ClearMinValue();
+ rFmtFldStepMain.ClearMaxValue();
+ Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter();
+ rFmtFldOrigin.ClearMinValue();
+ rFmtFldOrigin.ClearMaxValue();
+
+ m_xLB_AxisType->connect_changed(LINK(this, ScaleTabPage, SelectAxisTypeHdl));
+
+ HideAllControls();
+}
+
+ScaleTabPage::~ScaleTabPage()
+{
+}
+
+void ScaleTabPage::EnableControls()
+{
+ bool bValueAxis = m_nAxisType == chart2::AxisType::REALNUMBER
+ || m_nAxisType == chart2::AxisType::PERCENT
+ || m_nAxisType == chart2::AxisType::DATE;
+ bool bDateAxis = m_nAxisType == chart2::AxisType::DATE;
+
+ m_xBxType->set_visible(m_bAllowDateAxis);
+
+ m_xCbxLogarithm->set_visible( bValueAxis && !bDateAxis );
+
+ m_xBxMinMax->set_visible(bValueAxis);
+
+ m_xTxtMain->set_visible( bValueAxis );
+ m_xCbxAutoStepMain->set_visible( bValueAxis );
+
+ m_xTxtHelpCount->set_visible( bValueAxis && !bDateAxis );
+ m_xTxtHelp->set_visible( bDateAxis );
+ m_xMtStepHelp->set_visible( bValueAxis );
+ m_xCbxAutoStepHelp->set_visible( bValueAxis );
+
+ m_xBxOrigin->set_visible( m_bShowAxisOrigin && bValueAxis );
+ m_xBxResolution->set_visible( bDateAxis );
+
+ bool bWasDateAxis = m_xMt_MainDateStep->get_visible();
+ if( bWasDateAxis != bDateAxis )
+ {
+ //transport value from one to other control
+ if( bWasDateAxis )
+ lcl_setValue( *m_xFmtFldStepMain, m_xMt_MainDateStep->get_value() );
+ else
+ m_xMt_MainDateStep->set_value(m_xFmtFldStepMain->GetFormatter().GetValue());
+ }
+
+ m_xFmtFldStepMain->set_visible( bValueAxis && !bDateAxis );
+ m_xMt_MainDateStep->set_visible( bDateAxis );
+
+ m_xLB_MainTimeUnit->set_visible( bDateAxis );
+ m_xLB_HelpTimeUnit->set_visible( bDateAxis );
+
+ EnableValueHdl(*m_xCbxAutoMin);
+ EnableValueHdl(*m_xCbxAutoMax);
+ EnableValueHdl(*m_xCbxAutoStepMain);
+ EnableValueHdl(*m_xCbxAutoStepHelp);
+ EnableValueHdl(*m_xCbxAutoOrigin);
+ EnableValueHdl(*m_xCbx_AutoTimeResolution);
+}
+
+IMPL_LINK( ScaleTabPage, EnableValueHdl, weld::Toggleable&, rCbx, void )
+{
+ bool bEnable = !rCbx.get_active() && rCbx.get_sensitive();
+ if (&rCbx == m_xCbxAutoMin.get())
+ {
+ m_xFmtFldMin->set_sensitive( bEnable );
+ }
+ else if (&rCbx == m_xCbxAutoMax.get())
+ {
+ m_xFmtFldMax->set_sensitive( bEnable );
+ }
+ else if (&rCbx == m_xCbxAutoStepMain.get())
+ {
+ m_xFmtFldStepMain->set_sensitive( bEnable );
+ m_xMt_MainDateStep->set_sensitive( bEnable );
+ m_xLB_MainTimeUnit->set_sensitive( bEnable );
+ }
+ else if (&rCbx == m_xCbxAutoStepHelp.get())
+ {
+ m_xMtStepHelp->set_sensitive( bEnable );
+ m_xLB_HelpTimeUnit->set_sensitive( bEnable );
+ }
+ else if (&rCbx == m_xCbx_AutoTimeResolution.get())
+ {
+ m_xLB_TimeResolution->set_sensitive( bEnable );
+ }
+ else if (&rCbx == m_xCbxAutoOrigin.get())
+ {
+ m_xFmtFldOrigin->set_sensitive( bEnable );
+ }
+}
+
+namespace {
+
+enum AxisTypeListBoxEntry
+{
+ TYPE_AUTO=0,
+ TYPE_TEXT=1,
+ TYPE_DATE=2
+};
+
+}
+
+IMPL_LINK_NOARG(ScaleTabPage, SelectAxisTypeHdl, weld::ComboBox&, void)
+{
+ const sal_Int32 nPos = m_xLB_AxisType->get_active();
+ if( nPos==TYPE_DATE )
+ m_nAxisType = chart2::AxisType::DATE;
+ else
+ m_nAxisType = chart2::AxisType::CATEGORY;
+ if( m_nAxisType == chart2::AxisType::DATE )
+ m_xCbxLogarithm->set_active(false);
+ EnableControls();
+ SetNumFormat();
+}
+
+std::unique_ptr<SfxTabPage> ScaleTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<ScaleTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool ScaleTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ OSL_PRECOND( pNumFormatter, "No NumberFormatter available" );
+
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXISTYPE, m_nAxisType));
+ if(m_bAllowDateAxis)
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_DATEAXIS, m_xLB_AxisType->get_active()==TYPE_AUTO));
+
+ bool bAutoScale = false;
+ if( m_nAxisType==chart2::AxisType::CATEGORY )
+ bAutoScale = true;//reset scaling for category charts
+
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_MIN ,bAutoScale || m_xCbxAutoMin->get_active()));
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_MAX ,bAutoScale || m_xCbxAutoMax->get_active()));
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_STEP_HELP,bAutoScale || m_xCbxAutoStepHelp->get_active()));
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_ORIGIN ,bAutoScale || m_xCbxAutoOrigin->get_active()));
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_LOGARITHM ,m_xCbxLogarithm->get_active()));
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_REVERSE ,m_xCbxReverse->get_active()));
+ rOutAttrs->Put(SvxDoubleItem(fMax , SCHATTR_AXIS_MAX));
+ rOutAttrs->Put(SvxDoubleItem(fMin , SCHATTR_AXIS_MIN));
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_STEP_HELP, nStepHelp));
+ rOutAttrs->Put(SvxDoubleItem(fOrigin , SCHATTR_AXIS_ORIGIN));
+
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_STEP_MAIN,bAutoScale || m_xCbxAutoStepMain->get_active()));
+ rOutAttrs->Put(SvxDoubleItem(fStepMain,SCHATTR_AXIS_STEP_MAIN));
+
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_AXIS_AUTO_TIME_RESOLUTION,bAutoScale || m_xCbx_AutoTimeResolution->get_active()));
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_TIME_RESOLUTION,m_nTimeResolution));
+
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_MAIN_TIME_UNIT,m_nMainTimeUnit));
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS_HELP_TIME_UNIT,m_nHelpTimeUnit));
+
+ return true;
+}
+
+void ScaleTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ OSL_PRECOND( pNumFormatter, "No NumberFormatter available" );
+ if(!pNumFormatter)
+ return;
+
+ if (const SfxBoolItem* pDateAxisItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_ALLOW_DATEAXIS))
+ m_bAllowDateAxis = pDateAxisItem->GetValue();
+ m_nAxisType=chart2::AxisType::REALNUMBER;
+ if (const SfxInt32Item* pAxisTypeItem = rInAttrs->GetItemIfSet(SCHATTR_AXISTYPE))
+ m_nAxisType = static_cast<int>(pAxisTypeItem->GetValue());
+ if( m_nAxisType==chart2::AxisType::DATE && !m_bAllowDateAxis )
+ m_nAxisType=chart2::AxisType::CATEGORY;
+ if( m_bAllowDateAxis )
+ {
+ bool bAutoDateAxis = false;
+ if (const SfxBoolItem* pDateAxisItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_DATEAXIS))
+ bAutoDateAxis = pDateAxisItem->GetValue();
+
+ sal_uInt16 nPos = 0;
+ if( m_nAxisType==chart2::AxisType::DATE )
+ nPos=TYPE_DATE;
+ else if( bAutoDateAxis )
+ nPos=TYPE_AUTO;
+ else
+ nPos=TYPE_TEXT;
+ m_xLB_AxisType->set_active( nPos );
+ }
+
+ m_xCbxAutoMin->set_active(true);
+ m_xCbxAutoMax->set_active(true);
+ m_xCbxAutoStepMain->set_active(true);
+ m_xCbxAutoStepHelp->set_active(true);
+ m_xCbxAutoOrigin->set_active(true);
+ m_xCbx_AutoTimeResolution->set_active(true);
+
+ if (const SfxBoolItem* pAutoMinItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_MIN))
+ m_xCbxAutoMin->set_active(pAutoMinItem->GetValue());
+
+ if (const SvxDoubleItem* pAxisMinItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_MIN))
+ {
+ fMin = pAxisMinItem->GetValue();
+ lcl_setValue( *m_xFmtFldMin, fMin );
+ m_xFmtFldMin->save_value();
+ }
+
+ if (const SfxBoolItem* pAutoMaxItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_MAX))
+ m_xCbxAutoMax->set_active(pAutoMaxItem->GetValue());
+
+ if (const SvxDoubleItem* pAxisMaxItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_MAX))
+ {
+ fMax = pAxisMaxItem->GetValue();
+ lcl_setValue( *m_xFmtFldMax, fMax );
+ m_xFmtFldMax->save_value();
+ }
+
+ if (const SfxBoolItem* pAutoStepMainItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_STEP_MAIN))
+ m_xCbxAutoStepMain->set_active(pAutoStepMainItem->GetValue());
+
+ if (const SvxDoubleItem* pStepMainItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_STEP_MAIN))
+ {
+ fStepMain = pStepMainItem->GetValue();
+ lcl_setValue( *m_xFmtFldStepMain, fStepMain );
+ m_xFmtFldStepMain->save_value();
+ m_xMt_MainDateStep->set_value( static_cast<sal_Int32>(fStepMain) );
+ m_xMt_MainDateStep->save_value();
+ }
+ if (const SfxBoolItem* pAutoStepHelpItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_STEP_HELP))
+ m_xCbxAutoStepHelp->set_active(pAutoStepHelpItem->GetValue());
+ if (const SfxBoolItem* pLogItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_LOGARITHM))
+ m_xCbxLogarithm->set_active(pLogItem->GetValue());
+ if (const SfxBoolItem* pReverseItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_REVERSE))
+ m_xCbxReverse->set_active(pReverseItem->GetValue());
+ if (const SfxInt32Item* pStepHelpItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_STEP_HELP))
+ {
+ nStepHelp = pStepHelpItem->GetValue();
+ m_xMtStepHelp->set_value( nStepHelp );
+ m_xMtStepHelp->save_value();
+ }
+ if (const SfxBoolItem* pOriginItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_ORIGIN))
+ m_xCbxAutoOrigin->set_active(pOriginItem->GetValue());
+ if (const SvxDoubleItem* pOriginItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_ORIGIN))
+ {
+ fOrigin = pOriginItem->GetValue();
+ lcl_setValue( *m_xFmtFldOrigin, fOrigin );
+ m_xFmtFldOrigin->save_value();
+ }
+
+ if (const SfxBoolItem* pAutoTimeResItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_AUTO_TIME_RESOLUTION))
+ m_xCbx_AutoTimeResolution->set_active(pAutoTimeResItem->GetValue());
+ if (const SfxInt32Item* pTimeResItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_TIME_RESOLUTION))
+ {
+ m_nTimeResolution = pTimeResItem->GetValue();
+ m_xLB_TimeResolution->set_active( m_nTimeResolution );
+ }
+
+ if (const SfxInt32Item* pMainTimeUnitItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_MAIN_TIME_UNIT))
+ {
+ m_nMainTimeUnit = pMainTimeUnitItem->GetValue();
+ m_xLB_MainTimeUnit->set_active( m_nMainTimeUnit );
+ }
+ if (const SfxInt32Item* pHelpTimeUnitItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_HELP_TIME_UNIT))
+ {
+ m_nHelpTimeUnit = pHelpTimeUnitItem->GetValue();
+ m_xLB_HelpTimeUnit->set_active( m_nHelpTimeUnit );
+ }
+
+ EnableControls();
+ SetNumFormat();
+}
+
+DeactivateRC ScaleTabPage::DeactivatePage(SfxItemSet* pItemSet)
+{
+ if( !pNumFormatter )
+ {
+ OSL_FAIL( "No NumberFormatter available" );
+ return DeactivateRC::LeavePage;
+ }
+
+ bool bDateAxis = m_nAxisType == chart2::AxisType::DATE;
+
+ sal_uInt32 nMinMaxOriginFmt = m_xFmtFldMax->GetFormatter().GetFormatKey();
+ if (pNumFormatter->GetType(nMinMaxOriginFmt) == SvNumFormatType::TEXT)
+ nMinMaxOriginFmt = 0;
+ // numberformat_text cause numbers to fail being numbers... Shouldn't happen, but can.
+ sal_uInt32 nStepFmt = m_xFmtFldStepMain->GetFormatter().GetFormatKey();
+ if (pNumFormatter->GetType(nStepFmt) == SvNumFormatType::TEXT)
+ nStepFmt = 0;
+
+ weld::Widget* pControl = nullptr;
+ TranslateId pErrStrId;
+ double fDummy;
+
+ fMax = m_xFmtFldMax->GetFormatter().GetValue();
+ fMin = m_xFmtFldMin->GetFormatter().GetValue();
+ fOrigin = m_xFmtFldOrigin->GetFormatter().GetValue();
+ fStepMain = bDateAxis ? m_xMt_MainDateStep->get_value() : m_xFmtFldStepMain->GetFormatter().GetValue();
+ nStepHelp = m_xMtStepHelp->get_value();
+ m_nTimeResolution = m_xLB_TimeResolution->get_active();
+ m_nMainTimeUnit = m_xLB_MainTimeUnit->get_active();
+ m_nHelpTimeUnit = m_xLB_HelpTimeUnit->get_active();
+
+ if( m_nAxisType != chart2::AxisType::REALNUMBER )
+ m_xCbxLogarithm->hide();
+
+ //check which entries need user action
+
+ if ( m_xCbxLogarithm->get_active() &&
+ ( ( !m_xCbxAutoMin->get_active() && fMin <= 0.0 )
+ || ( !m_xCbxAutoMax->get_active() && fMax <= 0.0 ) ) )
+ {
+ pControl = m_xFmtFldMin.get();
+ pErrStrId = STR_BAD_LOGARITHM;
+ }
+ // check for entries that cannot be parsed for the current number format
+ else if ( m_xFmtFldMin->get_value_changed_from_saved()
+ && !m_xCbxAutoMin->get_active()
+ && !pNumFormatter->IsNumberFormat( m_xFmtFldMin->get_text(), nMinMaxOriginFmt, fDummy))
+ {
+ pControl = m_xFmtFldMin.get();
+ pErrStrId = STR_INVALID_NUMBER;
+ }
+ else if ( m_xFmtFldMax->get_value_changed_from_saved()
+ && !m_xCbxAutoMax->get_active()
+ && !pNumFormatter->IsNumberFormat( m_xFmtFldMax->get_text(), nMinMaxOriginFmt, fDummy))
+ {
+ pControl = m_xFmtFldMax.get();
+ pErrStrId = STR_INVALID_NUMBER;
+ }
+ else if ( !bDateAxis && m_xFmtFldStepMain->get_value_changed_from_saved()
+ && !m_xCbxAutoStepMain->get_active()
+ && !pNumFormatter->IsNumberFormat( m_xFmtFldStepMain->get_text(), nStepFmt, fDummy))
+ {
+ pControl = m_xFmtFldStepMain.get();
+ pErrStrId = STR_INVALID_NUMBER;
+ }
+ else if (m_xFmtFldOrigin->get_value_changed_from_saved() && !m_xCbxAutoOrigin->get_active() &&
+ !pNumFormatter->IsNumberFormat( m_xFmtFldOrigin->get_text(), nMinMaxOriginFmt, fDummy))
+ {
+ pControl = m_xFmtFldOrigin.get();
+ pErrStrId = STR_INVALID_NUMBER;
+ }
+ else if (!m_xCbxAutoStepMain->get_active() && fStepMain <= 0.0)
+ {
+ pControl = m_xFmtFldStepMain.get();
+ pErrStrId = STR_STEP_GT_ZERO;
+ }
+ else if (!m_xCbxAutoMax->get_active() && !m_xCbxAutoMin->get_active() &&
+ fMin >= fMax)
+ {
+ pControl = m_xFmtFldMin.get();
+ pErrStrId = STR_MIN_GREATER_MAX;
+ }
+ else if( bDateAxis )
+ {
+ if( !m_xCbxAutoStepMain->get_active() && !m_xCbxAutoStepHelp->get_active() )
+ {
+ if( m_nHelpTimeUnit > m_nMainTimeUnit )
+ {
+ pControl = m_xLB_MainTimeUnit.get();
+ pErrStrId = STR_INVALID_INTERVALS;
+ }
+ else if( m_nHelpTimeUnit == m_nMainTimeUnit && nStepHelp > fStepMain )
+ {
+ pControl = m_xLB_MainTimeUnit.get();
+ pErrStrId = STR_INVALID_INTERVALS;
+ }
+ }
+ if( !pErrStrId && !m_xCbx_AutoTimeResolution->get_active() )
+ {
+ if( (!m_xCbxAutoStepMain->get_active() && m_nTimeResolution > m_nMainTimeUnit )
+ ||
+ (!m_xCbxAutoStepHelp->get_active() && m_nTimeResolution > m_nHelpTimeUnit )
+ )
+ {
+ pControl = m_xLB_TimeResolution.get();
+ pErrStrId = STR_INVALID_TIME_UNIT;
+ }
+ }
+ }
+
+ if( ShowWarning( pErrStrId, pControl ) )
+ return DeactivateRC::KeepPage;
+
+ if( pItemSet )
+ FillItemSet( pItemSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void ScaleTabPage::SetNumFormatter( SvNumberFormatter* pFormatter )
+{
+ pNumFormatter = pFormatter;
+
+ Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter();
+ Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter();
+ Formatter& rFmtFldStepMain = m_xFmtFldStepMain->GetFormatter();
+ Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter();
+
+ rFmtFldMax.SetFormatter( pNumFormatter );
+ rFmtFldMin.SetFormatter( pNumFormatter );
+ rFmtFldStepMain.SetFormatter( pNumFormatter );
+ rFmtFldOrigin.SetFormatter( pNumFormatter );
+
+ // #i6278# allow more decimal places than the output format. As
+ // the numbers shown in the edit fields are used for input, it makes more
+ // sense to display the values in the input format rather than the output
+ // format.
+ rFmtFldMax.UseInputStringForFormatting();
+ rFmtFldMin.UseInputStringForFormatting();
+ rFmtFldStepMain.UseInputStringForFormatting();
+ rFmtFldOrigin.UseInputStringForFormatting();
+
+ SetNumFormat();
+}
+
+void ScaleTabPage::SetNumFormat()
+{
+ const SfxUInt32Item *pNumFormatItem = GetItemSet().GetItemIfSet( SID_ATTR_NUMBERFORMAT_VALUE );
+
+ if( !pNumFormatItem )
+ return;
+
+ sal_uInt32 nFmt = pNumFormatItem->GetValue();
+
+ Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter();
+ rFmtFldMax.SetFormatKey(nFmt);
+ Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter();
+ rFmtFldMin.SetFormatKey(nFmt);
+ Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter();
+ rFmtFldOrigin.SetFormatKey(nFmt);
+
+ if( pNumFormatter )
+ {
+ SvNumFormatType eType = pNumFormatter->GetType( nFmt );
+ if( eType == SvNumFormatType::DATE )
+ {
+ // for intervals use standard format for dates (so you can enter a number of days)
+ const SvNumberformat* pFormat = pNumFormatter->GetEntry( nFmt );
+ if( pFormat )
+ nFmt = pNumFormatter->GetStandardIndex( pFormat->GetLanguage());
+ else
+ nFmt = pNumFormatter->GetStandardIndex();
+ }
+ else if( eType == SvNumFormatType::DATETIME )
+ {
+ // for intervals use time format for date times
+ const SvNumberformat* pFormat = pNumFormatter->GetEntry( nFmt );
+ if( pFormat )
+ nFmt = pNumFormatter->GetStandardFormat( SvNumFormatType::TIME, pFormat->GetLanguage() );
+ else
+ nFmt = pNumFormatter->GetStandardFormat( SvNumFormatType::TIME );
+
+ // tdf#141625 give enough space to see full date+time
+ int nWidestTime(m_xFmtFldMin->get_pixel_size(getWidestDateTime(Application::GetSettings().GetLocaleDataWrapper(), true)).Width());
+ int nWidthChars = std::ceil(nWidestTime / m_xFmtFldMin->get_approximate_digit_width()) + 1;
+ m_xFmtFldMin->set_width_chars(nWidthChars);
+ m_xFmtFldMax->set_width_chars(nWidthChars);
+ }
+
+ if( m_nAxisType == chart2::AxisType::DATE && ( eType != SvNumFormatType::DATE && eType != SvNumFormatType::DATETIME) )
+ {
+ const SvNumberformat* pFormat = pNumFormatter->GetEntry( nFmt );
+ if( pFormat )
+ nFmt = pNumFormatter->GetStandardFormat( SvNumFormatType::DATE, pFormat->GetLanguage() );
+ else
+ nFmt = pNumFormatter->GetStandardFormat( SvNumFormatType::DATE );
+
+ rFmtFldMax.SetFormatKey(nFmt);
+ rFmtFldMin.SetFormatKey(nFmt);
+ rFmtFldOrigin.SetFormatKey(nFmt);
+ }
+ }
+
+ m_xFmtFldStepMain->GetFormatter().SetFormatKey(nFmt);
+}
+
+void ScaleTabPage::ShowAxisOrigin( bool bShowOrigin )
+{
+ m_bShowAxisOrigin = bShowOrigin;
+ if( !AxisHelper::isAxisPositioningEnabled() )
+ m_bShowAxisOrigin = true;
+}
+
+bool ScaleTabPage::ShowWarning(TranslateId pResIdMessage, weld::Widget* pControl /* = nullptr */)
+{
+ if (!pResIdMessage)
+ return false;
+
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ SchResId(pResIdMessage)));
+ xWarn->run();
+ if (pControl)
+ {
+ pControl->grab_focus();
+ weld::Entry* pEdit = dynamic_cast<weld::Entry*>(pControl);
+ if (pEdit)
+ pEdit->select_region(0, -1);
+ }
+ return true;
+}
+
+void ScaleTabPage::HideAllControls()
+{
+ // We need to set these controls invisible when the class is instantiated
+ // since some code in EnableControls() depends on that logic. The real
+ // visibility of these controls depend on axis data type, and are
+ // set in EnableControls().
+
+ m_xBxType->hide();
+ m_xCbxLogarithm->hide();
+ m_xBxMinMax->hide();
+ m_xTxtMain->hide();
+ m_xFmtFldStepMain->hide();
+ m_xMt_MainDateStep->hide();
+ m_xLB_MainTimeUnit->hide();
+ m_xCbxAutoStepMain->hide();
+ m_xTxtHelpCount->hide();
+ m_xTxtHelp->hide();
+ m_xMtStepHelp->hide();
+ m_xCbxAutoStepHelp->hide();
+ m_xBxOrigin->hide();
+ m_xBxResolution->hide();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Scale.hxx b/chart2/source/controller/dialogs/tp_Scale.hxx
new file mode 100644
index 0000000000..b90d3ef202
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Scale.hxx
@@ -0,0 +1,109 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <unotools/resmgr.hxx>
+
+namespace chart
+{
+
+class ScaleTabPage : public SfxTabPage
+{
+public:
+ ScaleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~ScaleTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pItemSet ) override;
+
+ void SetNumFormatter( SvNumberFormatter* pFormatter );
+ void SetNumFormat();
+
+ void ShowAxisOrigin( bool bShowOrigin );
+
+private:
+ double fMin;
+ double fMax;
+ double fStepMain;
+ sal_Int32 nStepHelp;
+ double fOrigin;
+ sal_Int32 m_nTimeResolution;
+ sal_Int32 m_nMainTimeUnit;
+ sal_Int32 m_nHelpTimeUnit;
+ int m_nAxisType;
+ bool m_bAllowDateAxis;
+ SvNumberFormatter* pNumFormatter;
+
+ bool m_bShowAxisOrigin;
+
+ std::unique_ptr<weld::CheckButton> m_xCbxReverse;
+ std::unique_ptr<weld::CheckButton> m_xCbxLogarithm;
+ std::unique_ptr<weld::Widget> m_xBxType;
+ std::unique_ptr<weld::ComboBox> m_xLB_AxisType;
+ std::unique_ptr<weld::Widget> m_xBxMinMax;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFldMin;
+ std::unique_ptr<weld::CheckButton> m_xCbxAutoMin;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFldMax;
+ std::unique_ptr<weld::CheckButton> m_xCbxAutoMax;
+ std::unique_ptr<weld::Widget> m_xBxResolution;
+ std::unique_ptr<weld::ComboBox> m_xLB_TimeResolution;
+ std::unique_ptr<weld::CheckButton> m_xCbx_AutoTimeResolution;
+ std::unique_ptr<weld::Label> m_xTxtMain;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFldStepMain;
+ std::unique_ptr<weld::SpinButton> m_xMt_MainDateStep;
+ std::unique_ptr<weld::ComboBox> m_xLB_MainTimeUnit;
+ std::unique_ptr<weld::CheckButton> m_xCbxAutoStepMain;
+ std::unique_ptr<weld::Label> m_xTxtHelpCount;
+ std::unique_ptr<weld::Label> m_xTxtHelp;
+ std::unique_ptr<weld::SpinButton> m_xMtStepHelp;
+ std::unique_ptr<weld::ComboBox> m_xLB_HelpTimeUnit;
+ std::unique_ptr<weld::CheckButton> m_xCbxAutoStepHelp;
+ std::unique_ptr<weld::FormattedSpinButton> m_xFmtFldOrigin;
+ std::unique_ptr<weld::CheckButton> m_xCbxAutoOrigin;
+ std::unique_ptr<weld::Widget> m_xBxOrigin;
+
+ void EnableControls();
+
+ DECL_LINK(SelectAxisTypeHdl, weld::ComboBox&, void);
+ DECL_LINK(EnableValueHdl, weld::Toggleable&, void);
+
+ /** shows a warning window due to an invalid input.
+
+ @param pResIdMessage
+ The resource identifier that represents the localized warning text.
+ If this is nullptr, no warning is shown and false is returned.
+
+ @param pControl
+ If non-NULL, contains a pointer to the control in which the
+ erroneous value was in. This method gives this control the focus
+ and selects its content.
+
+ @return false, if nResIdMessage was 0, true otherwise
+ */
+ bool ShowWarning(TranslateId pResIdMessage, weld::Widget* pControl);
+
+ void HideAllControls();
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_SeriesToAxis.cxx b/chart2/source/controller/dialogs/tp_SeriesToAxis.cxx
new file mode 100644
index 0000000000..3ffbc3642e
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_SeriesToAxis.cxx
@@ -0,0 +1,248 @@
+/* -*- 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 .
+ */
+
+#include "tp_SeriesToAxis.hxx"
+
+#include <chartview/ChartSfxItemIds.hxx>
+
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/ilstitem.hxx>
+
+#include <com/sun/star/chart/MissingValueTreatment.hpp>
+
+namespace chart
+{
+
+SchOptionTabPage::SchOptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_SeriesToAxis.ui", "TP_OPTIONS", &rInAttrs)
+ , m_nAllSeriesAxisIndex(0)
+ , m_bProvidesSecondaryYAxis(true)
+ , m_bProvidesOverlapAndGapWidth(false)
+ , m_bProvidesBarConnectors(false)
+ , m_xGrpAxis(m_xBuilder->weld_widget("frameGrpAxis"))
+ , m_xRbtAxis1(m_xBuilder->weld_radio_button("RBT_OPT_AXIS_1"))
+ , m_xRbtAxis2(m_xBuilder->weld_radio_button("RBT_OPT_AXIS_2"))
+ , m_xGrpBar(m_xBuilder->weld_widget("frameSettings"))
+ , m_xMTGap(m_xBuilder->weld_metric_spin_button("MT_GAP", FieldUnit::PERCENT))
+ , m_xMTOverlap(m_xBuilder->weld_metric_spin_button("MT_OVERLAP", FieldUnit::PERCENT))
+ , m_xCBConnect(m_xBuilder->weld_check_button("CB_CONNECTOR"))
+ , m_xCBAxisSideBySide(m_xBuilder->weld_check_button("CB_BARS_SIDE_BY_SIDE"))
+ , m_xGrpPlotOptions(m_xBuilder->weld_widget("frameFL_PLOT_OPTIONS"))
+ , m_xGridPlotOptions(m_xBuilder->weld_widget("gridPLOT_OPTIONS"))
+ , m_xRB_DontPaint(m_xBuilder->weld_radio_button("RB_DONT_PAINT"))
+ , m_xRB_AssumeZero(m_xBuilder->weld_radio_button("RB_ASSUME_ZERO"))
+ , m_xRB_ContinueLine(m_xBuilder->weld_radio_button("RB_CONTINUE_LINE"))
+ , m_xCBIncludeHiddenCells(m_xBuilder->weld_check_button("CB_INCLUDE_HIDDEN_CELLS"))
+ , m_xCBHideLegendEntry(m_xBuilder->weld_check_button("CB_LEGEND_ENTRY_HIDDEN"))
+{
+ m_xRbtAxis1->connect_toggled(LINK(this, SchOptionTabPage, EnableHdl));
+ m_xRbtAxis2->connect_toggled(LINK(this, SchOptionTabPage, EnableHdl));
+}
+
+SchOptionTabPage::~SchOptionTabPage()
+{
+}
+
+IMPL_LINK_NOARG(SchOptionTabPage, EnableHdl, weld::Toggleable&, void)
+{
+ if( m_nAllSeriesAxisIndex == 0 )
+ m_xCBAxisSideBySide->set_sensitive( m_xRbtAxis2->get_active());
+ else if( m_nAllSeriesAxisIndex == 1 )
+ m_xCBAxisSideBySide->set_sensitive( m_xRbtAxis1->get_active());
+}
+
+std::unique_ptr<SfxTabPage> SchOptionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SchOptionTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool SchOptionTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ if(m_xRbtAxis2->get_active())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS,CHART_AXIS_SECONDARY_Y));
+ else
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_AXIS,CHART_AXIS_PRIMARY_Y));
+
+ if(m_xMTGap->get_visible())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_BAR_GAPWIDTH,static_cast< sal_Int32 >( m_xMTGap->get_value(FieldUnit::PERCENT))));
+
+ if(m_xMTOverlap->get_visible())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_BAR_OVERLAP,static_cast< sal_Int32 >( m_xMTOverlap->get_value(FieldUnit::PERCENT))));
+
+ if(m_xCBConnect->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_BAR_CONNECT,m_xCBConnect->get_active()));
+
+ // model property is "group bars per axis", UI feature is the other way
+ // round: "show bars side by side"
+ if(m_xCBAxisSideBySide->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_GROUP_BARS_PER_AXIS, ! m_xCBAxisSideBySide->get_active()));
+
+ if(m_xRB_DontPaint->get_active())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_MISSING_VALUE_TREATMENT,css::chart::MissingValueTreatment::LEAVE_GAP));
+ else if(m_xRB_AssumeZero->get_active())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_MISSING_VALUE_TREATMENT,css::chart::MissingValueTreatment::USE_ZERO));
+ else if(m_xRB_ContinueLine->get_active())
+ rOutAttrs->Put(SfxInt32Item(SCHATTR_MISSING_VALUE_TREATMENT,css::chart::MissingValueTreatment::CONTINUE));
+
+ if (m_xCBIncludeHiddenCells->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_INCLUDE_HIDDEN_CELLS, m_xCBIncludeHiddenCells->get_active()));
+
+ if(m_xCBHideLegendEntry->get_visible())
+ rOutAttrs->Put(SfxBoolItem(SCHATTR_HIDE_LEGEND_ENTRY, m_xCBHideLegendEntry->get_active()));
+
+ return true;
+}
+
+void SchOptionTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ m_xRbtAxis1->set_active(true);
+ m_xRbtAxis2->set_active(false);
+ if (const SfxInt32Item* pAxisItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS))
+ {
+ tools::Long nVal = pAxisItem->GetValue();
+ if(nVal==CHART_AXIS_SECONDARY_Y)
+ {
+ m_xRbtAxis2->set_active(true);
+ m_xRbtAxis1->set_active(false);
+ }
+ }
+
+ tools::Long nTmp;
+ if (const SfxInt32Item* pGapWidthItem = rInAttrs->GetItemIfSet(SCHATTR_BAR_GAPWIDTH))
+ {
+ nTmp = static_cast<tools::Long>(pGapWidthItem->GetValue());
+ m_xMTGap->set_value(nTmp, FieldUnit::PERCENT);
+ }
+
+ if (const SfxInt32Item* pOverlapItem = rInAttrs->GetItemIfSet(SCHATTR_BAR_OVERLAP))
+ {
+ nTmp = static_cast<tools::Long>(pOverlapItem->GetValue());
+ m_xMTOverlap->set_value(nTmp, FieldUnit::PERCENT);
+ }
+
+ if (const SfxBoolItem* pConnectItem = rInAttrs->GetItemIfSet(SCHATTR_BAR_CONNECT))
+ {
+ bool bCheck = pConnectItem->GetValue();
+ m_xCBConnect->set_active(bCheck);
+ }
+
+ if (const SfxInt32Item* pAllSeriesItem = rInAttrs->GetItemIfSet(SCHATTR_AXIS_FOR_ALL_SERIES))
+ {
+ m_nAllSeriesAxisIndex = pAllSeriesItem->GetValue();
+ m_xCBAxisSideBySide->set_sensitive(false);
+ }
+ if (const SfxBoolItem* pPerAxisItem = rInAttrs->GetItemIfSet(SCHATTR_GROUP_BARS_PER_AXIS))
+ {
+ // model property is "group bars per axis", UI feature is the other way
+ // round: "show bars side by side"
+ bool bCheck = ! pPerAxisItem->GetValue();
+ m_xCBAxisSideBySide->set_active( bCheck );
+ }
+ else
+ {
+ m_xCBAxisSideBySide->hide();
+ }
+
+ //missing value treatment
+ {
+ std::vector< sal_Int32 > aMissingValueTreatments;
+ if (const SfxIntegerListItem* pValueTreatmentsItem = rInAttrs->GetItemIfSet(SCHATTR_AVAILABLE_MISSING_VALUE_TREATMENTS))
+ aMissingValueTreatments = pValueTreatmentsItem->GetList();
+
+ const SfxInt32Item* pMissingValueTreatmentItem;
+ if ( aMissingValueTreatments.size()>1 &&
+ (pMissingValueTreatmentItem = rInAttrs->GetItemIfSet(SCHATTR_MISSING_VALUE_TREATMENT)) )
+ {
+ m_xRB_DontPaint->set_sensitive(false);
+ m_xRB_AssumeZero->set_sensitive(false);
+ m_xRB_ContinueLine->set_sensitive(false);
+
+ for(int nVal : aMissingValueTreatments)
+ {
+ if(nVal==css::chart::MissingValueTreatment::LEAVE_GAP)
+ m_xRB_DontPaint->set_sensitive(true);
+ else if(nVal==css::chart::MissingValueTreatment::USE_ZERO)
+ m_xRB_AssumeZero->set_sensitive(true);
+ else if(nVal==css::chart::MissingValueTreatment::CONTINUE)
+ m_xRB_ContinueLine->set_sensitive(true);
+ }
+
+ tools::Long nVal=pMissingValueTreatmentItem->GetValue();
+ if(nVal==css::chart::MissingValueTreatment::LEAVE_GAP)
+ m_xRB_DontPaint->set_active(true);
+ else if(nVal==css::chart::MissingValueTreatment::USE_ZERO)
+ m_xRB_AssumeZero->set_active(true);
+ else if(nVal==css::chart::MissingValueTreatment::CONTINUE)
+ m_xRB_ContinueLine->set_active(true);
+ }
+ else
+ {
+ m_xGridPlotOptions->hide();
+ }
+ }
+
+ // Include hidden cells
+ if (const SfxBoolItem* pHiddenCellsItem = rInAttrs->GetItemIfSet(SCHATTR_INCLUDE_HIDDEN_CELLS))
+ {
+ bool bVal = pHiddenCellsItem->GetValue();
+ m_xCBIncludeHiddenCells->set_active(bVal);
+ }
+ else
+ {
+ m_xCBIncludeHiddenCells->hide();
+ // check if the radiobutton guys above
+ // are visible. If they aren't, we can
+ // as well hide the whole frame
+ if(!m_xGridPlotOptions->get_visible())
+ m_xGrpPlotOptions->hide();
+ }
+
+ if (const SfxBoolItem* pEntryItem = rInAttrs->GetItemIfSet(SCHATTR_HIDE_LEGEND_ENTRY))
+ {
+ bool bVal = pEntryItem->GetValue();
+ m_xCBHideLegendEntry->set_active(bVal);
+ }
+
+ AdaptControlPositionsAndVisibility();
+}
+
+void SchOptionTabPage::Init( bool bProvidesSecondaryYAxis, bool bProvidesOverlapAndGapWidth, bool bProvidesBarConnectors )
+{
+ m_bProvidesSecondaryYAxis = bProvidesSecondaryYAxis;
+ m_bProvidesOverlapAndGapWidth = bProvidesOverlapAndGapWidth;
+ m_bProvidesBarConnectors = bProvidesBarConnectors;
+
+ AdaptControlPositionsAndVisibility();
+}
+
+void SchOptionTabPage::AdaptControlPositionsAndVisibility()
+{
+ m_xGrpAxis->set_visible(m_bProvidesSecondaryYAxis);
+ m_xGrpBar->set_visible(m_bProvidesOverlapAndGapWidth);
+ m_xCBConnect->set_visible(m_bProvidesBarConnectors);
+
+ if (!m_xMTGap->get_visible() && !m_xMTOverlap->get_visible())
+ m_xGrpBar->hide();
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx b/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx
new file mode 100644
index 0000000000..6b163f3c88
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_SeriesToAxis.hxx
@@ -0,0 +1,77 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace weld {
+ class CheckButton;
+ class MetricSpinButton;
+ class RadioButton;
+ class ToggleButton;
+ class Widget;
+}
+
+namespace chart
+{
+
+class SchOptionTabPage : public SfxTabPage
+{
+public:
+ SchOptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SchOptionTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+
+ void Init( bool bProvidesSecondaryYAxis, bool bProvidesOverlapAndGapWidth, bool bProvidesBarConnectors );
+
+private: //methods
+ void AdaptControlPositionsAndVisibility();
+
+private: //member
+ DECL_LINK(EnableHdl, weld::Toggleable&, void );
+
+ sal_Int32 m_nAllSeriesAxisIndex;
+
+ bool m_bProvidesSecondaryYAxis;
+ bool m_bProvidesOverlapAndGapWidth;
+ bool m_bProvidesBarConnectors;
+
+ std::unique_ptr<weld::Widget> m_xGrpAxis;
+ std::unique_ptr<weld::RadioButton> m_xRbtAxis1;
+ std::unique_ptr<weld::RadioButton> m_xRbtAxis2;
+ std::unique_ptr<weld::Widget> m_xGrpBar;
+ std::unique_ptr<weld::MetricSpinButton> m_xMTGap;
+ std::unique_ptr<weld::MetricSpinButton> m_xMTOverlap;
+ std::unique_ptr<weld::CheckButton> m_xCBConnect;
+ std::unique_ptr<weld::CheckButton> m_xCBAxisSideBySide;
+ std::unique_ptr<weld::Widget> m_xGrpPlotOptions;
+ std::unique_ptr<weld::Widget> m_xGridPlotOptions;
+ std::unique_ptr<weld::RadioButton> m_xRB_DontPaint;
+ std::unique_ptr<weld::RadioButton> m_xRB_AssumeZero;
+ std::unique_ptr<weld::RadioButton> m_xRB_ContinueLine;
+ std::unique_ptr<weld::CheckButton> m_xCBIncludeHiddenCells;
+ std::unique_ptr<weld::CheckButton> m_xCBHideLegendEntry;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_TitleRotation.cxx b/chart2/source/controller/dialogs/tp_TitleRotation.cxx
new file mode 100644
index 0000000000..f3380042eb
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_TitleRotation.cxx
@@ -0,0 +1,121 @@
+/* -*- 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 .
+ */
+
+#include "tp_TitleRotation.hxx"
+
+#include <chartview/ChartSfxItemIds.hxx>
+#include <TextDirectionListBox.hxx>
+
+#include <editeng/eeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/sdangitm.hxx>
+
+namespace chart
+{
+
+SchAlignmentTabPage::SchAlignmentTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, bool bWithRotation)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/titlerotationtabpage.ui", "TitleRotationTabPage", &rInAttrs)
+ , m_xFtRotate(m_xBuilder->weld_label("degreeL"))
+ , m_xNfRotate(m_xBuilder->weld_metric_spin_button("OrientDegree", FieldUnit::DEGREE))
+ , m_xCbStacked(m_xBuilder->weld_check_button("stackedCB"))
+ , m_xFtABCD(m_xBuilder->weld_label("labelABCD"))
+ , m_aLbTextDirection(m_xBuilder->weld_combo_box("textdirLB"))
+ , m_xCtrlDial(new svx::DialControl)
+ , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, "dialCtrl", *m_xCtrlDial))
+{
+ m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
+ m_xCtrlDial->SetText(m_xFtABCD->get_label());
+ m_xCbStacked->connect_toggled(LINK(this, SchAlignmentTabPage, StackedToggleHdl));
+
+ m_xCtrlDialWin->set_sensitive(true);
+ m_xNfRotate->set_sensitive(true);
+ m_xCbStacked->set_sensitive(true);
+ m_xFtRotate->set_sensitive(true);
+
+ if( !bWithRotation )
+ {
+ m_xCtrlDialWin->hide();
+ m_xNfRotate->hide();
+ m_xCbStacked->hide();
+ m_xFtRotate->hide();
+ }
+}
+
+IMPL_LINK_NOARG(SchAlignmentTabPage, StackedToggleHdl, weld::Toggleable&, void)
+{
+ bool bActive = m_xCbStacked->get_active();
+ m_xNfRotate->set_sensitive(!bActive);
+ m_xCtrlDialWin->set_sensitive(!bActive);
+ m_xCtrlDial->StyleUpdated();
+ m_xFtRotate->set_sensitive(!bActive);
+}
+
+SchAlignmentTabPage::~SchAlignmentTabPage()
+{
+ m_xCtrlDialWin.reset();
+ m_xCtrlDial.reset();
+}
+
+std::unique_ptr<SfxTabPage> SchAlignmentTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rInAttrs)
+{
+ return std::make_unique<SchAlignmentTabPage>(pPage, pController, *rInAttrs);
+}
+
+std::unique_ptr<SfxTabPage> SchAlignmentTabPage::CreateWithoutRotation(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rInAttrs)
+{
+ return std::make_unique<SchAlignmentTabPage>(pPage, pController, *rInAttrs, false);
+}
+
+bool SchAlignmentTabPage::FillItemSet(SfxItemSet* rOutAttrs)
+{
+ //Since 04/1998 text can be rotated by an arbitrary angle: SCHATTR_TEXT_DEGREES
+ bool bStacked = m_xCbStacked->get_active();
+ rOutAttrs->Put( SfxBoolItem( SCHATTR_TEXT_STACKED, bStacked ) );
+
+ Degree100 nDegrees = bStacked ? 0_deg100 : m_xCtrlDial->GetRotation();
+ rOutAttrs->Put( SdrAngleItem( SCHATTR_TEXT_DEGREES, nDegrees ) );
+
+ SvxFrameDirection aDirection( m_aLbTextDirection.get_active_id() );
+ rOutAttrs->Put( SvxFrameDirectionItem( aDirection, EE_PARA_WRITINGDIR ) );
+
+ return true;
+}
+
+void SchAlignmentTabPage::Reset(const SfxItemSet* rInAttrs)
+{
+ const SfxPoolItem* pItem = GetItem( *rInAttrs, SCHATTR_TEXT_DEGREES );
+
+ Degree100 nDegrees = pItem ? static_cast<const SdrAngleItem*>(pItem)->GetValue() : 0_deg100;
+ m_xCtrlDial->SetRotation( nDegrees );
+
+ pItem = GetItem( *rInAttrs, SCHATTR_TEXT_STACKED );
+ bool bStacked = pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xCbStacked->set_active(bStacked);
+ StackedToggleHdl(*m_xCbStacked);
+
+ if( const SvxFrameDirectionItem* pDirectionItem = rInAttrs->GetItemIfSet(EE_PARA_WRITINGDIR) )
+ m_aLbTextDirection.set_active_id(pDirectionItem->GetValue());
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_TitleRotation.hxx b/chart2/source/controller/dialogs/tp_TitleRotation.hxx
new file mode 100644
index 0000000000..9d59b693f9
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_TitleRotation.hxx
@@ -0,0 +1,61 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/dialcontrol.hxx>
+#include <TextDirectionListBox.hxx>
+
+namespace weld {
+ class CheckButton;
+ class CustomWeld;
+ class Label;
+ class SpinButton;
+ class ToggleButton;
+}
+
+namespace chart
+{
+
+class SchAlignmentTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::Label> m_xFtRotate;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfRotate;
+ std::unique_ptr<weld::CheckButton> m_xCbStacked;
+ std::unique_ptr<weld::Label> m_xFtABCD;
+ TextDirectionListBox m_aLbTextDirection;
+ std::unique_ptr<svx::DialControl> m_xCtrlDial;
+ std::unique_ptr<weld::CustomWeld> m_xCtrlDialWin;
+
+ DECL_LINK(StackedToggleHdl, weld::Toggleable&, void);
+
+public:
+ SchAlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs, bool bWithRotation = true);
+ virtual ~SchAlignmentTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ static std::unique_ptr<SfxTabPage> CreateWithoutRotation(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs);
+ virtual bool FillItemSet(SfxItemSet* rOutAttrs) override;
+ virtual void Reset(const SfxItemSet* rInAttrs) override;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Trendline.cxx b/chart2/source/controller/dialogs/tp_Trendline.cxx
new file mode 100644
index 0000000000..fe25959bdd
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Trendline.cxx
@@ -0,0 +1,59 @@
+/* -*- 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 .
+ */
+
+#include "tp_Trendline.hxx"
+
+namespace chart
+{
+
+TrendlineTabPage::TrendlineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "modules/schart/ui/tp_Trendline.ui", "TP_TRENDLINE", &rInAttrs)
+ , m_aTrendlineResources(*m_xBuilder, rInAttrs)
+{
+}
+
+std::unique_ptr<SfxTabPage> TrendlineTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<TrendlineTabPage>(pPage, pController, *rOutAttrs);
+}
+
+bool TrendlineTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ m_aTrendlineResources.FillItemSet( rOutAttrs );
+ return true;
+}
+
+void TrendlineTabPage::Reset( const SfxItemSet* rInAttrs )
+{
+ m_aTrendlineResources.Reset( *rInAttrs );
+}
+
+void TrendlineTabPage::SetNumFormatter( SvNumberFormatter* pNumFormatter )
+{
+ m_aTrendlineResources.SetNumFormatter( pNumFormatter );
+}
+
+void TrendlineTabPage::SetNbPoints( sal_Int32 nNbPoints )
+{
+ m_aTrendlineResources.SetNbPoints( nNbPoints );
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Trendline.hxx b/chart2/source/controller/dialogs/tp_Trendline.hxx
new file mode 100644
index 0000000000..3a240af387
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Trendline.hxx
@@ -0,0 +1,46 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include "res_Trendline.hxx"
+
+#include <sfx2/tabdlg.hxx>
+
+namespace chart
+{
+
+class TrendlineTabPage : public SfxTabPage
+{
+public:
+ TrendlineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+ void SetNumFormatter( SvNumberFormatter* pFormatter );
+ void SetNbPoints( sal_Int32 nNbPoints );
+
+private:
+ TrendlineResources m_aTrendlineResources;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx
new file mode 100644
index 0000000000..e0fd6a51f8
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx
@@ -0,0 +1,160 @@
+/* -*- 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 .
+ */
+
+#include "tp_Wizard_TitlesAndObjects.hxx"
+#include <res_Titles.hxx>
+#include <res_LegendPosition.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <Diagram.hxx>
+#include <AxisHelper.hxx>
+#include <ControllerLockGuard.hxx>
+#include <utility>
+
+namespace chart
+{
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::chart2;
+
+TitlesAndObjectsTabPage::TitlesAndObjectsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ rtl::Reference<::chart::ChartModel> xChartModel,
+ const uno::Reference< uno::XComponentContext >& xContext )
+ : OWizardPage(pPage, pController, "modules/schart/ui/wizelementspage.ui", "WizElementsPage")
+ , m_xTitleResources(new TitleResources(*m_xBuilder, false))
+ , m_xLegendPositionResources(new LegendPositionResources(*m_xBuilder, xContext))
+ , m_xChartModel(std::move(xChartModel))
+ , m_xCC(xContext)
+ , m_bCommitToModel(true)
+ , m_aTimerTriggeredControllerLock( m_xChartModel )
+ , m_xCB_Grid_X(m_xBuilder->weld_check_button("x"))
+ , m_xCB_Grid_Y(m_xBuilder->weld_check_button("y"))
+ , m_xCB_Grid_Z(m_xBuilder->weld_check_button("z"))
+{
+ m_xTitleResources->connect_changed( LINK( this, TitlesAndObjectsTabPage, ChangeEditHdl ));
+ m_xLegendPositionResources->SetChangeHdl( LINK( this, TitlesAndObjectsTabPage, ChangeHdl ));
+
+ m_xCB_Grid_X->connect_toggled( LINK( this, TitlesAndObjectsTabPage, ChangeCheckBoxHdl ));
+ m_xCB_Grid_Y->connect_toggled( LINK( this, TitlesAndObjectsTabPage, ChangeCheckBoxHdl ));
+ m_xCB_Grid_Z->connect_toggled( LINK( this, TitlesAndObjectsTabPage, ChangeCheckBoxHdl ));
+}
+
+TitlesAndObjectsTabPage::~TitlesAndObjectsTabPage()
+{
+}
+
+void TitlesAndObjectsTabPage::initializePage()
+{
+ m_bCommitToModel = false;
+
+ //init titles
+ {
+ TitleDialogData aTitleInput;
+ aTitleInput.readFromModel( m_xChartModel );
+ m_xTitleResources->writeToResources( aTitleInput );
+ }
+
+ //init legend
+ {
+ m_xLegendPositionResources->writeToResources( m_xChartModel );
+ }
+
+ //init grid checkboxes
+ {
+ rtl::Reference< Diagram > xDiagram = m_xChartModel->getFirstChartDiagram();
+ uno::Sequence< sal_Bool > aPossibilityList;
+ uno::Sequence< sal_Bool > aExistenceList;
+ AxisHelper::getAxisOrGridPossibilities( aPossibilityList, xDiagram, false );
+ AxisHelper::getAxisOrGridExistence( aExistenceList, xDiagram, false );
+ m_xCB_Grid_X->set_sensitive( aPossibilityList[0] );
+ m_xCB_Grid_Y->set_sensitive( aPossibilityList[1] );
+ m_xCB_Grid_Z->set_sensitive( aPossibilityList[2] );
+ m_xCB_Grid_X->set_active( aExistenceList[0] );
+ m_xCB_Grid_Y->set_active( aExistenceList[1] );
+ m_xCB_Grid_Z->set_active( aExistenceList[2] );
+ }
+
+ m_bCommitToModel = true;
+}
+
+bool TitlesAndObjectsTabPage::commitPage( ::vcl::WizardTypes::CommitPageReason /*eReason*/ )
+{
+ if( m_xTitleResources->get_value_changed_from_saved() ) //titles may have changed in the meanwhile
+ commitToModel();
+ return true;//return false if this page should not be left
+}
+
+void TitlesAndObjectsTabPage::commitToModel()
+{
+ m_aTimerTriggeredControllerLock.startTimer();
+ rtl::Reference<::chart::ChartModel> xModel = m_xChartModel;
+
+ ControllerLockGuardUNO aLockedControllers( xModel );
+
+ //commit title changes to model
+ {
+ TitleDialogData aTitleOutput;
+ m_xTitleResources->readFromResources( aTitleOutput );
+ aTitleOutput.writeDifferenceToModel( xModel, m_xCC );
+ m_xTitleResources->save_value();
+ }
+
+ //commit legend changes to model
+ {
+ m_xLegendPositionResources->writeToModel( xModel );
+ }
+
+ //commit grid changes to model
+ {
+ rtl::Reference< Diagram > xDiagram = xModel->getFirstChartDiagram();
+ uno::Sequence< sal_Bool > aOldExistenceList;
+ AxisHelper::getAxisOrGridExistence( aOldExistenceList, xDiagram, false );
+ uno::Sequence< sal_Bool > aNewExistenceList(aOldExistenceList);
+ sal_Bool* pNewExistenceList = aNewExistenceList.getArray();
+ pNewExistenceList[0] = m_xCB_Grid_X->get_active();
+ pNewExistenceList[1] = m_xCB_Grid_Y->get_active();
+ pNewExistenceList[2] = m_xCB_Grid_Z->get_active();
+ AxisHelper::changeVisibilityOfGrids( xDiagram
+ , aOldExistenceList, aNewExistenceList );
+ }
+}
+
+IMPL_LINK_NOARG(TitlesAndObjectsTabPage, ChangeCheckBoxHdl, weld::Toggleable&, void)
+{
+ ChangeHdl(nullptr);
+}
+
+IMPL_LINK_NOARG(TitlesAndObjectsTabPage, ChangeEditHdl, weld::Entry&, void)
+{
+ ChangeHdl(nullptr);
+}
+
+IMPL_LINK_NOARG(TitlesAndObjectsTabPage, ChangeHdl, LinkParamNone*, void)
+{
+ if( m_bCommitToModel )
+ commitToModel();
+}
+
+bool TitlesAndObjectsTabPage::canAdvance() const
+{
+ return false;
+}
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx
new file mode 100644
index 0000000000..d2c30d8b43
--- /dev/null
+++ b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx
@@ -0,0 +1,72 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <TimerTriggeredControllerLock.hxx>
+
+#include <vcl/wizardmachine.hxx>
+#include <rtl/ref.hxx>
+
+#include <memory>
+
+namespace chart { class LegendPositionResources; }
+namespace chart { class TitleResources; }
+namespace com::sun::star::chart2 { class XChartDocument; }
+namespace com::sun::star::uno { class XComponentContext; }
+
+namespace chart
+{
+class ChartModel;
+
+class TitlesAndObjectsTabPage final : public vcl::OWizardPage
+{
+public:
+ TitlesAndObjectsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ rtl::Reference<::chart::ChartModel> xChartModel,
+ const css::uno::Reference< css::uno::XComponentContext >& xContext);
+ virtual ~TitlesAndObjectsTabPage() override;
+
+ virtual void initializePage() override;
+ virtual bool commitPage( ::vcl::WizardTypes::CommitPageReason eReason ) override;
+ virtual bool canAdvance() const override;
+
+private:
+ void commitToModel();
+ DECL_LINK( ChangeHdl, LinkParamNone*, void );
+ DECL_LINK( ChangeEditHdl, weld::Entry&, void );
+ DECL_LINK( ChangeCheckBoxHdl, weld::Toggleable&, void );
+
+ std::unique_ptr< TitleResources > m_xTitleResources;
+ std::unique_ptr< LegendPositionResources > m_xLegendPositionResources;
+
+ rtl::Reference<::chart::ChartModel> m_xChartModel;
+ css::uno::Reference< css::uno::XComponentContext> m_xCC;
+
+ bool m_bCommitToModel;
+ TimerTriggeredControllerLock m_aTimerTriggeredControllerLock;
+
+ std::unique_ptr<weld::CheckButton> m_xCB_Grid_X;
+ std::unique_ptr<weld::CheckButton> m_xCB_Grid_Y;
+ std::unique_ptr<weld::CheckButton> m_xCB_Grid_Z;
+};
+
+} //namespace chart
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */