summaryrefslogtreecommitdiffstats
path: root/chart2/source/controller/sidebar
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/controller/sidebar')
-rw-r--r--chart2/source/controller/sidebar/Chart2PanelFactory.cxx147
-rw-r--r--chart2/source/controller/sidebar/Chart2PanelFactory.hxx56
-rw-r--r--chart2/source/controller/sidebar/ChartAreaPanel.cxx551
-rw-r--r--chart2/source/controller/sidebar/ChartAreaPanel.hxx86
-rw-r--r--chart2/source/controller/sidebar/ChartAxisPanel.cxx373
-rw-r--r--chart2/source/controller/sidebar/ChartAxisPanel.hxx93
-rw-r--r--chart2/source/controller/sidebar/ChartColorWrapper.cxx233
-rw-r--r--chart2/source/controller/sidebar/ChartColorWrapper.hxx68
-rw-r--r--chart2/source/controller/sidebar/ChartElementsPanel.cxx662
-rw-r--r--chart2/source/controller/sidebar/ChartElementsPanel.hxx116
-rw-r--r--chart2/source/controller/sidebar/ChartErrorBarPanel.cxx425
-rw-r--r--chart2/source/controller/sidebar/ChartErrorBarPanel.hxx91
-rw-r--r--chart2/source/controller/sidebar/ChartLinePanel.cxx293
-rw-r--r--chart2/source/controller/sidebar/ChartLinePanel.hxx87
-rw-r--r--chart2/source/controller/sidebar/ChartSeriesPanel.cxx474
-rw-r--r--chart2/source/controller/sidebar/ChartSeriesPanel.hxx110
-rw-r--r--chart2/source/controller/sidebar/ChartSidebarModifyListener.cxx39
-rw-r--r--chart2/source/controller/sidebar/ChartSidebarModifyListener.hxx42
-rw-r--r--chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx84
-rw-r--r--chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx52
-rw-r--r--chart2/source/controller/sidebar/ChartTypePanel.cxx437
-rw-r--r--chart2/source/controller/sidebar/ChartTypePanel.hxx121
22 files changed, 4640 insertions, 0 deletions
diff --git a/chart2/source/controller/sidebar/Chart2PanelFactory.cxx b/chart2/source/controller/sidebar/Chart2PanelFactory.cxx
new file mode 100644
index 000000000..081322b09
--- /dev/null
+++ b/chart2/source/controller/sidebar/Chart2PanelFactory.cxx
@@ -0,0 +1,147 @@
+/* -*- 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 "Chart2PanelFactory.hxx"
+
+#include <sfx2/sidebar/SidebarPanelBase.hxx>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <cppuhelper/exc_hlp.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <vcl/weldutils.hxx>
+
+#include "ChartElementsPanel.hxx"
+#include "ChartTypePanel.hxx"
+#include "ChartSeriesPanel.hxx"
+#include <ChartController.hxx>
+#include "ChartAxisPanel.hxx"
+#include "ChartErrorBarPanel.hxx"
+#include "ChartAreaPanel.hxx"
+#include "ChartLinePanel.hxx"
+
+using namespace css::uno;
+
+namespace chart::sidebar {
+
+ChartPanelFactory::ChartPanelFactory()
+{
+}
+
+ChartPanelFactory::~ChartPanelFactory()
+{
+}
+
+Reference<css::ui::XUIElement> SAL_CALL ChartPanelFactory::createUIElement (
+ const OUString& rsResourceURL,
+ const ::css::uno::Sequence<css::beans::PropertyValue>& rArguments)
+{
+ Reference<css::ui::XUIElement> xElement;
+
+ try
+ {
+ const ::comphelper::NamedValueCollection aArguments (rArguments);
+ Reference<css::frame::XFrame> xFrame (aArguments.getOrDefault("Frame", Reference<css::frame::XFrame>()));
+ Reference<css::awt::XWindow> xParentWindow (aArguments.getOrDefault("ParentWindow", Reference<css::awt::XWindow>()));
+ Reference<css::frame::XController> xController (aArguments.getOrDefault("Controller", Reference<css::frame::XController>()));
+
+ weld::Widget* pParent(nullptr);
+ if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xParentWindow.get()))
+ pParent = pTunnel->getWidget();
+
+ if (!pParent)
+ throw RuntimeException(
+ "PanelFactory::createUIElement called without ParentWindow",
+ nullptr);
+ if ( ! xFrame.is())
+ throw RuntimeException(
+ "PanelFactory::createUIElement called without Frame",
+ nullptr);
+ if (!xController.is())
+ throw RuntimeException(
+ "ChartPanelFactory::createUIElement called without Controller",
+ nullptr);
+
+ ChartController* pController = dynamic_cast<ChartController*>(xController.get());
+ if (!pController)
+ throw RuntimeException(
+ "ChartPanelFactory::createUIElement called without valid ChartController",
+ nullptr);
+
+ std::unique_ptr<PanelLayout> xPanel;
+ if (rsResourceURL.endsWith("/ElementsPanel"))
+ xPanel = ChartElementsPanel::Create( pParent, pController );
+ else if (rsResourceURL.endsWith("/TypePanel"))
+ xPanel = std::make_unique<ChartTypePanel>(pParent, pController);
+ else if (rsResourceURL.endsWith("/SeriesPanel"))
+ xPanel = ChartSeriesPanel::Create(pParent, pController);
+ else if (rsResourceURL.endsWith("/AxisPanel"))
+ xPanel = ChartAxisPanel::Create(pParent, pController);
+ else if (rsResourceURL.endsWith("/ErrorBarPanel"))
+ xPanel = ChartErrorBarPanel::Create(pParent, pController);
+ else if (rsResourceURL.endsWith("/AreaPanel"))
+ xPanel = ChartAreaPanel::Create(pParent, xFrame, pController);
+ else if (rsResourceURL.endsWith("/LinePanel"))
+ xPanel = ChartLinePanel::Create(pParent, xFrame, pController);
+
+ if (xPanel)
+ xElement = sfx2::sidebar::SidebarPanelBase::Create(
+ rsResourceURL,
+ xFrame,
+ std::move(xPanel),
+ css::ui::LayoutSize(-1,-1,-1));
+ }
+ catch (const css::uno::RuntimeException &)
+ {
+ throw;
+ }
+ catch (const css::uno::Exception&)
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ throw css::lang::WrappedTargetRuntimeException(
+ "ChartPanelFactory::createUIElement exception",
+ nullptr, anyEx );
+ }
+
+ return xElement;
+}
+
+OUString ChartPanelFactory::getImplementationName()
+{
+ return "org.libreoffice.comp.chart2.sidebar.ChartPanelFactory";
+}
+
+sal_Bool ChartPanelFactory::supportsService(OUString const & ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+css::uno::Sequence<OUString> ChartPanelFactory::getSupportedServiceNames()
+{
+ return { "com.sun.star.ui.UIElementFactory" };
+}
+
+} // end of namespace chart::sidebar
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+org_libreoffice_comp_chart2_sidebar_ChartPanelFactory(css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new ::chart::sidebar::ChartPanelFactory());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/Chart2PanelFactory.hxx b/chart2/source/controller/sidebar/Chart2PanelFactory.hxx
new file mode 100644
index 000000000..87619f647
--- /dev/null
+++ b/chart2/source/controller/sidebar/Chart2PanelFactory.hxx
@@ -0,0 +1,56 @@
+/* -*- 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 <comphelper/compbase.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ui/XUIElementFactory.hpp>
+
+
+namespace chart::sidebar {
+
+typedef comphelper::WeakComponentImplHelper <
+ css::ui::XUIElementFactory, css::lang::XServiceInfo
+ > PanelFactoryInterfaceBase;
+
+class ChartPanelFactory final
+ : public PanelFactoryInterfaceBase
+{
+public:
+ ChartPanelFactory();
+ virtual ~ChartPanelFactory() override;
+
+ ChartPanelFactory(const ChartPanelFactory&) = delete;
+ const ChartPanelFactory& operator=(const ChartPanelFactory&) = delete;
+
+ // XUIElementFactory
+ virtual css::uno::Reference<css::ui::XUIElement> SAL_CALL createUIElement(
+ const OUString& rsResourceURL,
+ const ::css::uno::Sequence<css::beans::PropertyValue>& rArguments) override;
+
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override;
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+};
+
+} // end of namespace chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
new file mode 100644
index 000000000..b8bd8198b
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -0,0 +1,551 @@
+/* -*- 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 <sal/config.h>
+
+#include <string_view>
+
+#include "ChartAreaPanel.hxx"
+
+#include <ChartController.hxx>
+#include <ChartModel.hxx>
+#include <ViewElementListProvider.hxx>
+#include <PropertyHelper.hxx>
+
+#include <chartview/DrawModelWrapper.hxx>
+#include <com/sun/star/chart2/XDiagram.hpp>
+
+#include <sfx2/weldutils.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/unomid.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svx/tbcontrl.hxx>
+
+namespace chart::sidebar {
+
+namespace {
+
+SvxColorToolBoxControl* getColorToolBoxControl(const ToolbarUnoDispatcher& rColorDispatch)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController = rColorDispatch.GetControllerForCommand(".uno:FillColor");
+ SvxColorToolBoxControl* pToolBoxColorControl = dynamic_cast<SvxColorToolBoxControl*>(xController.get());
+ return pToolBoxColorControl;
+}
+
+OUString getCID(const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ css::uno::Any aAny = xSelectionSupplier->getSelection();
+ if (!aAny.hasValue())
+ {
+ // if no selection, default to diagram wall so sidebar can show some editable properties
+ ChartController* pController = dynamic_cast<ChartController*>(xController.get());
+ if (pController)
+ {
+ pController->select( css::uno::Any( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, u"" ) ) );
+ xSelectionSupplier = css::uno::Reference<css::view::XSelectionSupplier>(xController, css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ aAny = xSelectionSupplier->getSelection();
+ }
+
+ if (!aAny.hasValue())
+ return OUString();
+ }
+
+ OUString aCID;
+ aAny >>= aCID;
+
+ return aCID;
+}
+
+css::uno::Reference<css::beans::XPropertySet> getPropSet(
+ const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ OUString aCID = getCID(xModel);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ ObjectIdentifier::getObjectPropertySet(aCID, xModel);
+
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType == OBJECTTYPE_DIAGRAM)
+ {
+ css::uno::Reference<css::chart2::XDiagram> xDiagram(
+ xPropSet, css::uno::UNO_QUERY);
+ if (!xDiagram.is())
+ return xPropSet;
+
+ xPropSet.set(xDiagram->getWall());
+ }
+
+ return xPropSet;
+}
+
+ChartController* getController(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController>xController = xModel->getCurrentController();
+ if (!xController.is())
+ throw std::exception();
+
+ ChartController* pController = dynamic_cast<ChartController*>(xController.get());
+ if (!pController)
+ throw std::exception();
+
+ return pController;
+}
+
+ViewElementListProvider getViewElementListProvider( const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartController* pController = getController(xModel);
+ ViewElementListProvider aProvider = pController->getViewElementListProvider();
+ return aProvider;
+}
+
+DrawModelWrapper* getDrawModelWrapper(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartController* pController = getController(xModel);
+ return pController->GetDrawModelWrapper();
+}
+
+XFillGradientItem getXGradientForName(const css::uno::Reference<css::frame::XModel>& xModel,
+ const OUString& rName)
+{
+ css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, css::uno::UNO_QUERY);
+ css::uno::Reference<css::container::XNameAccess> xNameAccess(
+ xFact->createInstance("com.sun.star.drawing.GradientTable"), css::uno::UNO_QUERY);
+ if (!xNameAccess.is())
+ return XFillGradientItem();
+
+ if (!xNameAccess->hasByName(rName))
+ return XFillGradientItem();
+
+ css::uno::Any aAny = xNameAccess->getByName(rName);
+
+ XFillGradientItem aItem;
+ aItem.SetName(rName);
+ aItem.PutValue(aAny, MID_FILLGRADIENT);
+
+ return aItem;
+
+}
+
+XFillFloatTransparenceItem getXTransparencyGradientForName(const css::uno::Reference<css::frame::XModel>& xModel,
+ const OUString& rName)
+{
+ css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, css::uno::UNO_QUERY);
+ css::uno::Reference<css::container::XNameAccess> xNameAccess(
+ xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), css::uno::UNO_QUERY);
+ if (!xNameAccess.is())
+ return XFillFloatTransparenceItem();
+
+ if (!xNameAccess->hasByName(rName))
+ return XFillFloatTransparenceItem();
+
+ css::uno::Any aAny = xNameAccess->getByName(rName);
+
+ XFillFloatTransparenceItem aItem;
+ aItem.SetName(rName);
+ aItem.PutValue(aAny, MID_FILLGRADIENT);
+ aItem.SetEnabled(true);
+
+ return aItem;
+}
+
+XHatch getXHatchFromName(const css::uno::Reference<css::frame::XModel>& xModel,
+ OUString& rName)
+{
+ try
+ {
+ ViewElementListProvider aProvider = getViewElementListProvider(xModel);
+ XHatchListRef aRef = aProvider.GetHatchList();
+ size_t n = aRef->Count();
+ for (size_t i = 0; i < n; ++i)
+ {
+ const XHatchEntry* pHatch = aRef->GetHatch(i);
+ if (!pHatch)
+ continue;
+
+ if (pHatch->GetName().equalsIgnoreAsciiCase(rName))
+ {
+ // we need to update the hatch name
+ rName = pHatch->GetName();
+ return pHatch->GetHatch();
+ }
+ }
+ }
+ catch (...)
+ {
+ // ignore exception
+ }
+
+ return XHatch();
+}
+
+GraphicObject getXBitmapFromName(const css::uno::Reference<css::frame::XModel>& xModel,
+ std::u16string_view rName)
+{
+ try
+ {
+ ViewElementListProvider aProvider = getViewElementListProvider(xModel);
+ XBitmapListRef aBmpRef = aProvider.GetBitmapList();
+ XPatternListRef aPatRef = aProvider.GetPatternList();
+
+ size_t n = aBmpRef->Count();
+ for (size_t i = 0; i < n; ++i)
+ {
+ const XBitmapEntry* pBitmap = aBmpRef->GetBitmap(i);
+ if (!pBitmap)
+ continue;
+
+ if (pBitmap->GetName().equalsIgnoreAsciiCase(rName))
+ {
+ return pBitmap->GetGraphicObject();
+ }
+ }
+
+ // perhaps it's a pattern
+ size_t m = aPatRef->Count();
+ for (size_t i = 0; i < m; ++i)
+ {
+ const XBitmapEntry* pBitmap = aPatRef->GetBitmap(i);
+ if (!pBitmap)
+ continue;
+
+ if (pBitmap->GetName().equalsIgnoreAsciiCase(rName))
+ {
+ return pBitmap->GetGraphicObject();
+ }
+ }
+ }
+ catch (...)
+ {
+ // ignore exception
+ }
+
+ return GraphicObject();
+}
+
+class PreventUpdate
+{
+public:
+ explicit PreventUpdate(bool& bUpdate):
+ mbUpdate(bUpdate)
+ {
+ mbUpdate = false;
+ }
+
+ ~PreventUpdate()
+ {
+ mbUpdate = true;
+ }
+
+private:
+ bool& mbUpdate;
+};
+
+}
+
+std::unique_ptr<PanelLayout> ChartAreaPanel::Create(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw css::lang::IllegalArgumentException("no parent Window given to ChartAxisPanel::Create", nullptr, 0);
+ if (!rxFrame.is())
+ throw css::lang::IllegalArgumentException("no XFrame given to ChartAxisPanel::Create", nullptr, 1);
+
+ return std::make_unique<ChartAreaPanel>(pParent, rxFrame, pController);
+}
+
+ChartAreaPanel::ChartAreaPanel(weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController):
+ svx::sidebar::AreaPropertyPanelBase(pParent, rxFrame),
+ mxModel(pController->getChartModel()),
+ mxListener(new ChartSidebarModifyListener(this)),
+ mxSelectionListener(new ChartSidebarSelectionListener(this)),
+ mbUpdate(true),
+ mbModelValid(true),
+ maFillColorWrapper(mxModel, getColorToolBoxControl(*mxColorDispatch), "FillColor")
+{
+ std::vector<ObjectType> aAcceptedTypes { OBJECTTYPE_PAGE, OBJECTTYPE_DIAGRAM,
+ OBJECTTYPE_DATA_SERIES, OBJECTTYPE_DATA_POINT,
+ OBJECTTYPE_TITLE, OBJECTTYPE_LEGEND};
+ mxSelectionListener->setAcceptedTypes(std::move(aAcceptedTypes));
+ Initialize();
+}
+
+ChartAreaPanel::~ChartAreaPanel()
+{
+ doUpdateModel(nullptr);
+}
+
+void ChartAreaPanel::Initialize()
+{
+ mxModel->addModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+
+ SvxColorToolBoxControl* pToolBoxColor = getColorToolBoxControl(*mxColorDispatch);
+ pToolBoxColor->setColorSelectFunction(maFillColorWrapper);
+
+ updateData();
+}
+
+void ChartAreaPanel::setFillTransparence(const XFillTransparenceItem& rItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ xPropSet->setPropertyValue("FillTransparence", css::uno::Any(rItem.GetValue()));
+}
+
+void ChartAreaPanel::setFillFloatTransparence(
+ const XFillFloatTransparenceItem& rItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ if (!rItem.IsEnabled())
+ {
+ xPropSet->setPropertyValue("FillTransparenceGradientName", css::uno::Any(OUString()));
+ return;
+ }
+
+ const OUString& aName = rItem.GetName();
+ css::uno::Any aGradientVal;
+ rItem.QueryValue(aGradientVal, MID_FILLGRADIENT);
+ OUString aNewName = PropertyHelper::addTransparencyGradientUniqueNameToTable(aGradientVal, mxModel, aName);
+ xPropSet->setPropertyValue("FillTransparenceGradientName", css::uno::Any(aNewName));
+}
+
+void ChartAreaPanel::setFillStyle(const XFillStyleItem& rItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ xPropSet->setPropertyValue("FillStyle", css::uno::Any(rItem.GetValue()));
+}
+
+void ChartAreaPanel::setFillStyleAndColor(const XFillStyleItem* pStyleItem,
+ const XFillColorItem& rColorItem)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ if (pStyleItem)
+ xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
+ xPropSet->setPropertyValue("FillColor", css::uno::Any(rColorItem.GetValue()));
+}
+
+void ChartAreaPanel::setFillStyleAndGradient(const XFillStyleItem* pStyleItem,
+ const XFillGradientItem& rGradientItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ if (pStyleItem)
+ xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
+
+ const OUString& aName = rGradientItem.GetName();
+ css::uno::Any aGradientVal;
+ rGradientItem.QueryValue(aGradientVal, MID_FILLGRADIENT);
+ OUString aNewName = PropertyHelper::addGradientUniqueNameToTable(aGradientVal, mxModel, aName);
+ xPropSet->setPropertyValue("FillGradientName", css::uno::Any(aNewName));
+}
+
+void ChartAreaPanel::setFillStyleAndHatch(const XFillStyleItem* pStyleItem,
+ const XFillHatchItem& rHatchItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ if (pStyleItem)
+ xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
+ xPropSet->setPropertyValue("FillHatchName", css::uno::Any(rHatchItem.GetValue()));
+}
+
+void ChartAreaPanel::setFillStyleAndBitmap(const XFillStyleItem* pStyleItem,
+ const XFillBitmapItem& rBitmapItem)
+{
+ PreventUpdate aProtector(mbUpdate);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ if (pStyleItem)
+ xPropSet->setPropertyValue("FillStyle", css::uno::Any(pStyleItem->GetValue()));
+
+ css::uno::Any aBitmap;
+ rBitmapItem.QueryValue(aBitmap, MID_BITMAP);
+ const OUString& aPreferredName = rBitmapItem.GetName();
+ aBitmap <<= PropertyHelper::addBitmapUniqueNameToTable(aBitmap, mxModel, aPreferredName);
+ xPropSet->setPropertyValue("FillBitmapName", aBitmap);
+}
+
+void ChartAreaPanel::setFillUseBackground(const XFillStyleItem* pStyleItem,
+ const XFillUseSlideBackgroundItem& /*rItem*/)
+{
+ setFillStyle(*pStyleItem);
+}
+
+void ChartAreaPanel::updateData()
+{
+ if (!mbUpdate || !mbModelValid)
+ return;
+
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ css::uno::Reference<css::beans::XPropertySetInfo> xInfo(xPropSet->getPropertySetInfo());
+ if (!xInfo.is())
+ return;
+
+ SolarMutexGuard aGuard;
+ if (xInfo->hasPropertyByName("FillStyle"))
+ {
+ css::drawing::FillStyle eFillStyle = css::drawing::FillStyle_SOLID;
+ xPropSet->getPropertyValue("FillStyle") >>= eFillStyle;
+ XFillStyleItem aFillStyleItem(eFillStyle);
+ updateFillStyle(false, true, &aFillStyleItem);
+ }
+
+ if (xInfo->hasPropertyByName("FillTransparence"))
+ {
+ sal_uInt16 nFillTransparence = 0;
+ xPropSet->getPropertyValue("FillTransparence") >>= nFillTransparence;
+ SfxUInt16Item aTransparenceItem(0, nFillTransparence);
+ updateFillTransparence(false, true, &aTransparenceItem);
+ }
+
+ if (xInfo->hasPropertyByName("FillGradientName"))
+ {
+ OUString aGradientName;
+ xPropSet->getPropertyValue("FillGradientName") >>= aGradientName;
+ XFillGradientItem aGradientItem = getXGradientForName(mxModel, aGradientName);
+ updateFillGradient(false, true, &aGradientItem);
+ }
+
+ if (xInfo->hasPropertyByName("FillHatchName"))
+ {
+ OUString aHatchName;
+ xPropSet->getPropertyValue("FillHatchName") >>= aHatchName;
+ XHatch aHatch = getXHatchFromName(mxModel, aHatchName);
+ XFillHatchItem aHatchItem(aHatchName, aHatch);
+ updateFillHatch(false, true, &aHatchItem);
+ }
+
+ if (xInfo->hasPropertyByName("FillBitmapName"))
+ {
+ OUString aBitmapName;
+ xPropSet->getPropertyValue("FillBitmapName") >>= aBitmapName;
+ GraphicObject aBitmap = getXBitmapFromName(mxModel, aBitmapName);
+ XFillBitmapItem aBitmapItem(aBitmapName, aBitmap);
+ std::unique_ptr<XFillBitmapItem> pBitmapItem;
+ try
+ {
+ DrawModelWrapper* pModelWrapper = getDrawModelWrapper(mxModel);
+ if (pModelWrapper)
+ {
+ pBitmapItem = aBitmapItem.checkForUniqueItem(&pModelWrapper->getSdrModel());
+ }
+ }
+ catch (...)
+ {
+ }
+ updateFillBitmap(false, true, pBitmapItem ? pBitmapItem.get() : &aBitmapItem);
+ }
+
+ if (xInfo->hasPropertyByName("FillTransparenceGradientName"))
+ {
+ OUString aFillFloatTransparenceName;
+ xPropSet->getPropertyValue("FillTransparenceGradientName") >>= aFillFloatTransparenceName;
+ XFillFloatTransparenceItem aFillFloatTransparenceItem = getXTransparencyGradientForName(mxModel, aFillFloatTransparenceName);
+ updateFillFloatTransparence(false, true, &aFillFloatTransparenceItem);
+
+ maFillColorWrapper.updateData();
+ }
+
+ if (xInfo->hasPropertyByName("FillColor"))
+ {
+ sal_uInt32 nFillColor = 0;
+ xPropSet->getPropertyValue("FillColor") >>= nFillColor;
+ XFillColorItem aFillColorItem("", Color(ColorTransparency, nFillColor));
+ updateFillColor(true, &aFillColorItem);
+ }
+}
+
+void ChartAreaPanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartAreaPanel::selectionChanged(bool bCorrectType)
+{
+ if (bCorrectType)
+ updateData();
+}
+
+void ChartAreaPanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
+ mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (oldSelectionSupplier.is()) {
+ oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
+ }
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ mxModel->addModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+}
+
+void ChartAreaPanel::updateModel( css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.hxx b/chart2/source/controller/sidebar/ChartAreaPanel.hxx
new file mode 100644
index 000000000..75caf8d0d
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.hxx
@@ -0,0 +1,86 @@
+/* -*- 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/sidebar/SidebarModelUpdate.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+
+#include <svx/sidebar/AreaPropertyPanelBase.hxx>
+
+#include "ChartSidebarModifyListener.hxx"
+#include "ChartSidebarSelectionListener.hxx"
+#include "ChartColorWrapper.hxx"
+
+class XFillFloatTransparenceItem;
+class XFillTransparenceItem;
+class XFillColorItem;
+
+namespace chart {
+
+class ChartController;
+
+namespace sidebar {
+
+class ChartAreaPanel : public svx::sidebar::AreaPropertyPanelBase,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent,
+ public ChartSidebarSelectionListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController);
+
+ // constructor/destructor
+ ChartAreaPanel(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController);
+
+ virtual ~ChartAreaPanel() override;
+
+ virtual void setFillTransparence(const XFillTransparenceItem& rItem) override;
+ virtual void setFillFloatTransparence(const XFillFloatTransparenceItem& rItem) override;
+ virtual void setFillStyle(const XFillStyleItem& rItem) override;
+ virtual void setFillStyleAndColor(const XFillStyleItem* pStyleItem, const XFillColorItem& rColorItem) override;
+ virtual void setFillStyleAndGradient(const XFillStyleItem* pStyleItem, const XFillGradientItem& rGradientItem) override;
+ virtual void setFillStyleAndHatch(const XFillStyleItem* pStyleItem, const XFillHatchItem& rHatchItem) override;
+ virtual void setFillStyleAndBitmap(const XFillStyleItem* pStyleItem, const XFillBitmapItem& rBitmapItem) override;
+ virtual void setFillUseBackground(const XFillStyleItem* pStyleItem, const XFillUseSlideBackgroundItem& rItem) override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void selectionChanged(bool bCorrectType) override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+private:
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+ rtl::Reference<ChartSidebarSelectionListener> mxSelectionListener;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ bool mbUpdate;
+ bool mbModelValid;
+
+ ChartColorWrapper maFillColorWrapper;
+};
+
+} } // end of namespace svx::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartAxisPanel.cxx b/chart2/source/controller/sidebar/ChartAxisPanel.cxx
new file mode 100644
index 000000000..acc4a8add
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartAxisPanel.cxx
@@ -0,0 +1,373 @@
+/* -*- 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/chart/ChartAxisLabelPosition.hpp>
+#include <com/sun/star/chart2/AxisOrientation.hpp>
+
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+#include "ChartAxisPanel.hxx"
+#include <ChartController.hxx>
+#include <ChartModel.hxx>
+#include <Axis.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace chart::sidebar {
+
+namespace {
+
+bool isLabelShown(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< ::chart::Axis > xAxis = ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return false;
+
+ uno::Any aAny = xAxis->getPropertyValue("DisplayLabels");
+ if (!aAny.hasValue())
+ return false;
+
+ bool bVisible = false;
+ aAny >>= bVisible;
+ return bVisible;
+}
+
+void setLabelShown(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, bool bVisible)
+{
+ rtl::Reference< ::chart::Axis > xAxis = ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return;
+
+ xAxis->setPropertyValue("DisplayLabels", css::uno::Any(bVisible));
+}
+
+struct AxisLabelPosMap
+{
+ sal_Int32 nPos;
+ css::chart::ChartAxisLabelPosition ePos;
+};
+
+AxisLabelPosMap const aLabelPosMap[] = {
+ { 0, css::chart::ChartAxisLabelPosition_NEAR_AXIS },
+ { 1, css::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE },
+ { 2, css::chart::ChartAxisLabelPosition_OUTSIDE_START },
+ { 3, css::chart::ChartAxisLabelPosition_OUTSIDE_END }
+};
+
+sal_Int32 getLabelPosition(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< ::chart::Axis > xAxis = ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return 0;
+
+ uno::Any aAny = xAxis->getPropertyValue("LabelPosition");
+ if (!aAny.hasValue())
+ return 0;
+
+ css::chart::ChartAxisLabelPosition ePos;
+ aAny >>= ePos;
+ for (AxisLabelPosMap const & i : aLabelPosMap)
+ {
+ if (i.ePos == ePos)
+ return i.nPos;
+ }
+
+ return 0;
+}
+
+void setLabelPosition(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, sal_Int32 nPos)
+{
+ rtl::Reference< ::chart::Axis > xAxis = ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return;
+
+ css::chart::ChartAxisLabelPosition ePos;
+ for (AxisLabelPosMap const & i : aLabelPosMap)
+ {
+ if (i.nPos == nPos)
+ ePos = i.ePos;
+ }
+
+ xAxis->setPropertyValue("LabelPosition", css::uno::Any(ePos));
+}
+
+bool isReverse(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< Axis > xAxis =
+ ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return false;
+
+ css::chart2::ScaleData aData = xAxis->getScaleData();
+
+ return aData.Orientation == css::chart2::AxisOrientation_REVERSE;
+}
+
+void setReverse(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, bool bReverse)
+{
+ rtl::Reference< Axis > xAxis =
+ ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return;
+
+ css::chart2::ScaleData aData = xAxis->getScaleData();
+ if (bReverse)
+ aData.Orientation = css::chart2::AxisOrientation_REVERSE;
+ else
+ aData.Orientation = css::chart2::AxisOrientation_MATHEMATICAL;
+
+ xAxis->setScaleData(aData);
+}
+
+OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ uno::Any aAny = xSelectionSupplier->getSelection();
+ assert(aAny.hasValue());
+ OUString aCID;
+ aAny >>= aCID;
+#if defined DBG_UTIL && !defined NDEBUG
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if(eType != OBJECTTYPE_AXIS)
+ SAL_WARN("chart2","Selected item is not an axis");
+#endif
+
+ return aCID;
+}
+
+void setAxisRotation(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, double nVal)
+{
+ rtl::Reference< ::chart::Axis > xAxis =
+ ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return;
+
+ xAxis->setPropertyValue("TextRotation", css::uno::Any(nVal));
+}
+
+double getAxisRotation(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< ::chart::Axis > xAxis =
+ ObjectIdentifier::getAxisForCID(rCID, xModel);
+
+ if (!xAxis.is())
+ return 0;
+
+ css::uno::Any aAny = xAxis->getPropertyValue("TextRotation");
+ double nVal = 0;
+ aAny >>= nVal;
+ return nVal;
+}
+
+}
+
+ChartAxisPanel::ChartAxisPanel(
+ weld::Widget* pParent,
+ ChartController* pController)
+ : PanelLayout(pParent, "ChartAxisPanel", "modules/schart/ui/sidebaraxis.ui")
+ , mxCBShowLabel(m_xBuilder->weld_check_button("checkbutton_show_label"))
+ , mxCBReverse(m_xBuilder->weld_check_button("checkbutton_reverse"))
+ , mxLBLabelPos(m_xBuilder->weld_combo_box("comboboxtext_label_position"))
+ , mxGridLabel(m_xBuilder->weld_widget("label_props"))
+ , mxNFRotation(m_xBuilder->weld_metric_spin_button("spinbutton1", FieldUnit::DEGREE))
+ , mxModel(pController->getChartModel())
+ , mxModifyListener(new ChartSidebarModifyListener(this))
+ , mxSelectionListener(new ChartSidebarSelectionListener(this, OBJECTTYPE_AXIS))
+ , mbModelValid(true)
+{
+ Initialize();
+}
+
+ChartAxisPanel::~ChartAxisPanel()
+{
+ doUpdateModel(nullptr);
+
+ mxCBShowLabel.reset();
+ mxCBReverse.reset();
+
+ mxLBLabelPos.reset();
+ mxGridLabel.reset();
+
+ mxNFRotation.reset();
+}
+
+void ChartAxisPanel::Initialize()
+{
+ mxModel->addModifyListener(mxModifyListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+
+ updateData();
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, ChartAxisPanel, CheckBoxHdl);
+ mxCBShowLabel->connect_toggled(aLink);
+ mxCBReverse->connect_toggled(aLink);
+
+ Link<weld::MetricSpinButton&, void> aSpinButtonLink = LINK(this, ChartAxisPanel, TextRotationHdl);
+ mxNFRotation->connect_value_changed(aSpinButtonLink);
+
+ mxLBLabelPos->connect_changed(LINK(this, ChartAxisPanel, ListBoxHdl));
+}
+
+void ChartAxisPanel::updateData()
+{
+ if (!mbModelValid)
+ return;
+
+ OUString aCID = getCID(mxModel);
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType!=OBJECTTYPE_AXIS)
+ return;
+
+ SolarMutexGuard aGuard;
+
+ mxCBShowLabel->set_active(isLabelShown(mxModel, aCID));
+ mxCBReverse->set_active(isReverse(mxModel, aCID));
+
+ mxLBLabelPos->set_active(getLabelPosition(mxModel, aCID));
+ mxNFRotation->set_value(getAxisRotation(mxModel, aCID), FieldUnit::DEGREE);
+}
+
+std::unique_ptr<PanelLayout> ChartAxisPanel::Create (
+ weld::Widget* pParent,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw lang::IllegalArgumentException("no parent Window given to ChartAxisPanel::Create", nullptr, 0);
+ return std::make_unique<ChartAxisPanel>(pParent, pController);
+}
+
+void ChartAxisPanel::DataChanged(const DataChangedEvent& rEvent)
+{
+ PanelLayout::DataChanged(rEvent);
+ updateData();
+}
+
+void ChartAxisPanel::HandleContextChange(
+ const vcl::EnumContext& )
+{
+ updateData();
+}
+
+void ChartAxisPanel::NotifyItemUpdate(
+ sal_uInt16 /*nSID*/,
+ SfxItemState /*eState*/,
+ const SfxPoolItem* /*pState*/ )
+{
+}
+
+void ChartAxisPanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartAxisPanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxModifyListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
+ mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (oldSelectionSupplier.is()) {
+ oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
+ }
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ mxModel->addModifyListener(mxModifyListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+}
+
+void ChartAxisPanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+void ChartAxisPanel::selectionChanged(bool bCorrectType)
+{
+ if (bCorrectType)
+ updateData();
+}
+
+IMPL_LINK(ChartAxisPanel, CheckBoxHdl, weld::Toggleable&, rCheckbox, void)
+{
+ OUString aCID = getCID(mxModel);
+ bool bChecked = rCheckbox.get_active();
+
+ if (&rCheckbox == mxCBShowLabel.get())
+ {
+ mxGridLabel->set_sensitive(bChecked);
+ setLabelShown(mxModel, aCID, bChecked);
+ }
+ else if (&rCheckbox == mxCBReverse.get())
+ setReverse(mxModel, aCID, bChecked);
+}
+
+IMPL_LINK_NOARG(ChartAxisPanel, ListBoxHdl, weld::ComboBox&, void)
+{
+ OUString aCID = getCID(mxModel);
+ sal_Int32 nPos = mxLBLabelPos->get_active();
+
+ setLabelPosition(mxModel, aCID, nPos);
+}
+
+IMPL_LINK(ChartAxisPanel, TextRotationHdl, weld::MetricSpinButton&, rMetricField, void)
+{
+ OUString aCID = getCID(mxModel);
+ double nVal = rMetricField.get_value(FieldUnit::DEGREE);
+ setAxisRotation(mxModel, aCID, nVal);
+}
+
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartAxisPanel.hxx b/chart2/source/controller/sidebar/ChartAxisPanel.hxx
new file mode 100644
index 000000000..32f3c0b33
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartAxisPanel.hxx
@@ -0,0 +1,93 @@
+/* -*- 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/sidebar/ControllerItem.hxx>
+#include <sfx2/sidebar/IContextChangeReceiver.hxx>
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <sfx2/sidebar/PanelLayout.hxx>
+#include "ChartSidebarModifyListener.hxx"
+#include "ChartSidebarSelectionListener.hxx"
+
+namespace com::sun::star::util { class XModifyListener; }
+namespace com::sun::star::view { class XSelectionChangeListener; }
+
+namespace chart {
+
+class ChartController;
+
+namespace sidebar {
+
+class ChartAxisPanel : public PanelLayout,
+ public ::sfx2::sidebar::IContextChangeReceiver,
+ public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent,
+ public ChartSidebarSelectionListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ ChartController* pController);
+
+ virtual void DataChanged(
+ const DataChangedEvent& rEvent) override;
+
+ virtual void HandleContextChange(
+ const vcl::EnumContext& rContext) override;
+
+ virtual void NotifyItemUpdate(
+ const sal_uInt16 nSId,
+ const SfxItemState eState,
+ const SfxPoolItem* pState) override;
+
+ virtual void GetControlState(
+ const sal_uInt16 /*nSId*/,
+ boost::property_tree::ptree& /*rState*/) override {};
+
+ // constructor/destructor
+ ChartAxisPanel(
+ weld::Widget* pParent,
+ ChartController* pController);
+ virtual ~ChartAxisPanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void selectionChanged(bool bCorrectType) override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+private:
+ //ui controls
+ std::unique_ptr<weld::CheckButton> mxCBShowLabel;
+ std::unique_ptr<weld::CheckButton> mxCBReverse;
+ std::unique_ptr<weld::ComboBox> mxLBLabelPos;
+ std::unique_ptr<weld::Widget> mxGridLabel;
+ std::unique_ptr<weld::MetricSpinButton> mxNFRotation;
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxModifyListener;
+ css::uno::Reference<css::view::XSelectionChangeListener> mxSelectionListener;
+
+ bool mbModelValid;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ DECL_LINK(CheckBoxHdl, weld::Toggleable&, void);
+ DECL_LINK(ListBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(TextRotationHdl, weld::MetricSpinButton&, void);
+};
+
+} } // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartColorWrapper.cxx b/chart2/source/controller/sidebar/ChartColorWrapper.cxx
new file mode 100644
index 000000000..47df22d6e
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartColorWrapper.cxx
@@ -0,0 +1,233 @@
+/* -*- 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 <sal/config.h>
+
+#include <string_view>
+
+#include "ChartColorWrapper.hxx"
+#include <ChartModel.hxx>
+
+#include <ObjectIdentifier.hxx>
+#include <PropertyHelper.hxx>
+#include <com/sun/star/chart2/XDiagram.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/frame/XController.hpp>
+
+#include <svx/linectrl.hxx>
+#include <svx/tbcontrl.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/unomid.hxx>
+
+#include <comphelper/lok.hxx>
+#include <sal/log.hxx>
+#include <sfx2/viewsh.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
+namespace chart::sidebar {
+
+namespace {
+
+OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ css::uno::Any aAny = xSelectionSupplier->getSelection();
+ if (!aAny.hasValue())
+ return OUString();
+
+ OUString aCID;
+ aAny >>= aCID;
+
+ return aCID;
+}
+
+css::uno::Reference<css::beans::XPropertySet> getPropSet(
+ const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ OUString aCID = getCID(xModel);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ ObjectIdentifier::getObjectPropertySet(aCID, xModel);
+
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType == OBJECTTYPE_DIAGRAM)
+ {
+ css::uno::Reference<css::chart2::XDiagram> xDiagram(
+ xPropSet, css::uno::UNO_QUERY);
+ if (!xDiagram.is())
+ return xPropSet;
+
+ xPropSet.set(xDiagram->getWall());
+ }
+
+ return xPropSet;
+}
+
+}
+
+ChartColorWrapper::ChartColorWrapper(
+ rtl::Reference<::chart::ChartModel> const & xModel,
+ SvxColorToolBoxControl* pControl,
+ const OUString& rName):
+ mxModel(xModel),
+ mpControl(pControl),
+ maPropertyName(rName)
+{
+}
+
+void ChartColorWrapper::operator()([[maybe_unused]] const OUString& , const svx::NamedThemedColor& rColor)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+
+ if (!xPropSet.is())
+ {
+ SAL_WARN("chart2", "Invalid reference to xPropSet");
+ return;
+ }
+
+ xPropSet->setPropertyValue(maPropertyName, css::uno::Any(rColor.m_aColor));
+}
+
+void ChartColorWrapper::updateModel(const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ mxModel = xModel;
+}
+
+void ChartColorWrapper::updateData()
+{
+ static constexpr OUStringLiteral aLineColor = u"LineColor";
+ static const std::u16string_view aCommands[2] = {u".uno:XLineColor", u".uno:FillColor"};
+
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ css::util::URL aUrl;
+ aUrl.Complete = (maPropertyName == aLineColor) ? aCommands[0] : aCommands[1];
+
+ css::frame::FeatureStateEvent aEvent;
+ aEvent.FeatureURL = aUrl;
+ aEvent.IsEnabled = true;
+ aEvent.State = xPropSet->getPropertyValue(maPropertyName);
+ mpControl->statusChanged(aEvent);
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (comphelper::LibreOfficeKit::isActive() && pViewShell && (maPropertyName == aLineColor))
+ {
+ std::string sCommand = OUStringToOString(aUrl.Complete, RTL_TEXTENCODING_ASCII_US).getStr();
+ sal_Int32 nColor = -1;
+ aEvent.State >>= nColor;
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
+ (sCommand + "=" + std::to_string(nColor)).c_str());
+ }
+}
+
+ChartLineStyleWrapper::ChartLineStyleWrapper(
+ rtl::Reference<::chart::ChartModel> const & xModel,
+ SvxLineStyleToolBoxControl* pControl)
+ : mxModel(xModel)
+ , mpControl(pControl)
+{
+}
+
+void ChartLineStyleWrapper::updateModel(const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ mxModel = xModel;
+}
+
+namespace
+{
+ css::uno::Any getLineDash(
+ const css::uno::Reference<css::frame::XModel>& xModel, const OUString& rDashName)
+ {
+ css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, css::uno::UNO_QUERY);
+ css::uno::Reference<css::container::XNameAccess> xNameAccess(
+ xFact->createInstance("com.sun.star.drawing.DashTable"),
+ css::uno::UNO_QUERY );
+ if(xNameAccess.is())
+ {
+ if (!xNameAccess->hasByName(rDashName))
+ return css::uno::Any();
+
+ return xNameAccess->getByName(rDashName);
+ }
+
+ return css::uno::Any();
+ }
+}
+
+void ChartLineStyleWrapper::updateData()
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ css::util::URL aUrl;
+ aUrl.Complete = ".uno:XLineStyle";
+
+ css::frame::FeatureStateEvent aEvent;
+ aEvent.IsEnabled = true;
+
+ aEvent.FeatureURL = aUrl;
+ aEvent.State = xPropSet->getPropertyValue("LineStyle");
+ mpControl->statusChanged(aEvent);
+
+ aUrl.Complete = ".uno:LineDash";
+
+ auto aLineDashName = xPropSet->getPropertyValue("LineDashName");
+ OUString aDashName;
+ aLineDashName >>= aDashName;
+ css::uno::Any aLineDash = getLineDash(mxModel, aDashName);
+ XLineDashItem aDashItem;
+ aDashItem.PutValue(aLineDash, MID_LINEDASH);
+
+ aEvent.FeatureURL = aUrl;
+ aDashItem.QueryValue(aEvent.State);
+ mpControl->statusChanged(aEvent);
+}
+
+bool ChartLineStyleWrapper::operator()(std::u16string_view rCommand, const css::uno::Any& rValue)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+
+ if (!xPropSet.is())
+ {
+ SAL_WARN("chart2", "Invalid reference to xPropSet");
+ return false;
+ }
+
+ if (rCommand == u".uno:XLineStyle")
+ {
+ xPropSet->setPropertyValue("LineStyle", rValue);
+ return true;
+ }
+ else if (rCommand == u".uno:LineDash")
+ {
+ XLineDashItem aDashItem;
+ aDashItem.PutValue(rValue, 0);
+ css::uno::Any aAny;
+ aDashItem.QueryValue(aAny, MID_LINEDASH);
+ OUString aDashName = PropertyHelper::addLineDashUniqueNameToTable(aAny,
+ mxModel,
+ "");
+ xPropSet->setPropertyValue("LineDash", aAny);
+ xPropSet->setPropertyValue("LineDashName", css::uno::Any(aDashName));
+ return true;
+ }
+ return false;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartColorWrapper.hxx b/chart2/source/controller/sidebar/ChartColorWrapper.hxx
new file mode 100644
index 000000000..5237bc9c3
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartColorWrapper.hxx
@@ -0,0 +1,68 @@
+/* -*- 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 <ChartModel.hxx>
+
+#include <svx/Palette.hxx>
+#include <rtl/ref.hxx>
+
+namespace com::sun::star::frame { class XModel; }
+namespace chart { class ChartModel; }
+class SvxColorToolBoxControl;
+class SvxLineStyleToolBoxControl;
+
+namespace chart::sidebar {
+
+class ChartColorWrapper
+{
+public:
+ ChartColorWrapper(rtl::Reference<::chart::ChartModel> const & xModel,
+ SvxColorToolBoxControl* pControl,
+ const OUString& rPropertyName);
+
+ void operator()(const OUString& rCommand, const svx::NamedThemedColor& rColor);
+ // ColorSelectFunction signature
+
+ void updateModel(const rtl::Reference<::chart::ChartModel>& xModel);
+
+ void updateData();
+
+private:
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+
+ SvxColorToolBoxControl* mpControl;
+
+ OUString maPropertyName;
+};
+
+class ChartLineStyleWrapper
+{
+public:
+ ChartLineStyleWrapper(rtl::Reference<::chart::ChartModel> const & xModel,
+ SvxLineStyleToolBoxControl* pControl);
+
+ bool operator()(std::u16string_view rCommand, const css::uno::Any& rValue);
+
+ void updateModel(const rtl::Reference<::chart::ChartModel>& xModel);
+
+ void updateData();
+
+private:
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+
+ SvxLineStyleToolBoxControl* mpControl;
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartElementsPanel.cxx b/chart2/source/controller/sidebar/ChartElementsPanel.cxx
new file mode 100644
index 000000000..75dc7ed96
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartElementsPanel.cxx
@@ -0,0 +1,662 @@
+/* -*- 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/LegendPosition.hpp>
+#include <com/sun/star/chart/ChartLegendExpansion.hpp>
+
+#include <vcl/svapp.hxx>
+
+#include "ChartElementsPanel.hxx"
+#include <ChartController.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <Legend.hxx>
+#include <LegendHelper.hxx>
+#include <ChartModelHelper.hxx>
+#include <AxisHelper.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <ChartType.hxx>
+#include <ChartTypeHelper.hxx>
+#include <ChartModel.hxx>
+#include <BaseCoordinateSystem.hxx>
+
+
+using namespace css;
+using namespace css::uno;
+
+namespace chart::sidebar {
+
+namespace {
+
+enum class GridType
+{
+ VERT_MAJOR,
+ VERT_MINOR,
+ HOR_MAJOR,
+ HOR_MINOR
+};
+
+enum class AxisType
+{
+ X_MAIN,
+ Y_MAIN,
+ Z_MAIN,
+ X_SECOND,
+ Y_SECOND
+};
+
+ChartModel* getChartModel(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartModel* pModel = dynamic_cast<ChartModel*>(xModel.get());
+
+ return pModel;
+}
+
+bool isLegendVisible(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return false;
+
+ rtl::Reference< Legend > xLegendProp = LegendHelper::getLegend(*pModel);
+ if( xLegendProp.is())
+ {
+ try
+ {
+ bool bShow = false;
+ if( xLegendProp->getPropertyValue( "Show") >>= bShow )
+ {
+ return bShow;
+ }
+ }
+ catch(const uno::Exception &)
+ {
+ }
+ }
+
+ return false;
+}
+
+void setLegendVisible(const css::uno::Reference<css::frame::XModel>& xModel, bool bVisible)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return;
+
+ if (bVisible)
+ LegendHelper::showLegend(*pModel, comphelper::getProcessComponentContext());
+ else
+ LegendHelper::hideLegend(*pModel);
+}
+
+bool isLegendOverlay(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return false;
+
+ rtl::Reference< Legend > xLegendProp = LegendHelper::getLegend(*pModel);
+ if( xLegendProp.is())
+ {
+ try
+ {
+ bool bOverlay = false;
+ if(xLegendProp->getPropertyValue("Overlay") >>= bOverlay)
+ {
+ return bOverlay;
+ }
+ }
+ catch(const uno::Exception &)
+ {
+ }
+ }
+
+ return false;
+}
+
+void setLegendOverlay(const css::uno::Reference<css::frame::XModel>& xModel, bool bOverlay)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return;
+
+ rtl::Reference<Legend> xLegendProp = LegendHelper::getLegend(*pModel);
+ if (!xLegendProp.is())
+ return;
+
+ xLegendProp->setPropertyValue("Overlay", css::uno::Any(bOverlay));
+}
+
+bool isTitleVisible(const rtl::Reference<::chart::ChartModel>& xModel, TitleHelper::eTitleType eTitle)
+{
+ css::uno::Reference<css::uno::XInterface> xTitle = TitleHelper::getTitle(eTitle, xModel);
+ if (!xTitle.is())
+ return false;
+
+ css::uno::Reference<css::beans::XPropertySet> xPropSet(xTitle, css::uno::UNO_QUERY_THROW);
+ css::uno::Any aAny = xPropSet->getPropertyValue("Visible");
+ bool bVisible = aAny.get<bool>();
+ return bVisible;
+}
+
+bool isGridVisible(const rtl::Reference<::chart::ChartModel>& xModel, GridType eType)
+{
+ rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(xModel));
+ if(xDiagram.is())
+ {
+ sal_Int32 nDimensionIndex = 0;
+ if (eType == GridType::HOR_MAJOR || eType == GridType::HOR_MINOR)
+ nDimensionIndex = 1;
+
+ bool bMajor = (eType == GridType::HOR_MAJOR || eType == GridType::VERT_MAJOR);
+
+ bool bHasGrid = AxisHelper::isGridShown(nDimensionIndex, 0, bMajor, xDiagram);
+ return bHasGrid;
+ }
+ return false;
+}
+
+void setGridVisible(const rtl::Reference<::chart::ChartModel>& xModel, GridType eType, bool bVisible)
+{
+ rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(xModel));
+ if(!xDiagram.is())
+ return;
+
+ sal_Int32 nDimensionIndex = 0;
+ if (eType == GridType::HOR_MAJOR || eType == GridType::HOR_MINOR)
+ nDimensionIndex = 1;
+ sal_Int32 nCooSysIndex = 0;
+
+ bool bMajor = (eType == GridType::HOR_MAJOR || eType == GridType::VERT_MAJOR);
+
+ if (bVisible)
+ AxisHelper::showGrid(nDimensionIndex, nCooSysIndex, bMajor,
+ xDiagram);
+ else
+ AxisHelper::hideGrid(nDimensionIndex, nCooSysIndex, bMajor, xDiagram);
+}
+
+bool isAxisVisible(const rtl::Reference<::chart::ChartModel>& xModel, AxisType eType)
+{
+ rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(xModel));
+ if(xDiagram.is())
+ {
+ sal_Int32 nDimensionIndex = 0;
+ if (eType == AxisType::Y_MAIN || eType == AxisType::Y_SECOND)
+ nDimensionIndex = 1;
+ else if (eType == AxisType::Z_MAIN)
+ nDimensionIndex = 2;
+
+ bool bMajor = (eType != AxisType::X_SECOND && eType != AxisType::Y_SECOND);
+
+ bool bHasAxis = AxisHelper::isAxisShown(nDimensionIndex, bMajor, xDiagram);
+ return bHasAxis;
+ }
+ return false;
+}
+
+void setAxisVisible(const rtl::Reference<::chart::ChartModel>& xModel, AxisType eType, bool bVisible)
+{
+ rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(xModel));
+ if(!xDiagram.is())
+ return;
+
+ sal_Int32 nDimensionIndex = 0;
+ if (eType == AxisType::Y_MAIN || eType == AxisType::Y_SECOND)
+ nDimensionIndex = 1;
+ else if (eType == AxisType::Z_MAIN)
+ nDimensionIndex = 2;
+
+ bool bMajor = (eType != AxisType::X_SECOND && eType != AxisType::Y_SECOND);
+
+ if (bVisible)
+ AxisHelper::showAxis(nDimensionIndex, bMajor, xDiagram, comphelper::getProcessComponentContext());
+ else
+ AxisHelper::hideAxis(nDimensionIndex, bMajor, xDiagram);
+}
+
+sal_Int32 getLegendPos(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return -1;
+
+ rtl::Reference< Legend > xLegendProp = LegendHelper::getLegend(*pModel);
+ if (!xLegendProp.is())
+ return -1;
+
+ chart2::LegendPosition eLegendPos = chart2::LegendPosition_LINE_END;
+ xLegendProp->getPropertyValue("AnchorPosition") >>= eLegendPos;
+ switch(eLegendPos)
+ {
+ case chart2::LegendPosition_LINE_START:
+ return 3;
+ case chart2::LegendPosition_LINE_END:
+ return 0;
+ case chart2::LegendPosition_PAGE_START:
+ return 1;
+ case chart2::LegendPosition_PAGE_END:
+ return 2;
+ default:
+ return -1;
+ }
+}
+
+void setLegendPos(const css::uno::Reference<css::frame::XModel>& xModel, sal_Int32 nPos)
+{
+ ChartModel* pModel = getChartModel(xModel);
+ if (!pModel)
+ return;
+
+ rtl::Reference< Legend > xLegendProp = LegendHelper::getLegend(*pModel);
+ if (!xLegendProp.is())
+ return;
+
+ chart2::LegendPosition eLegendPos = chart2::LegendPosition_LINE_END;
+ css::chart::ChartLegendExpansion eExpansion = css::chart::ChartLegendExpansion_HIGH;
+ switch(nPos)
+ {
+ case 1:
+ eLegendPos = chart2::LegendPosition_PAGE_START;
+ eExpansion = css::chart::ChartLegendExpansion_WIDE;
+ break;
+ case 3:
+ eLegendPos = chart2::LegendPosition_LINE_START;
+ break;
+ case 0:
+ eLegendPos = chart2::LegendPosition_LINE_END;
+ break;
+ case 2:
+ eLegendPos = chart2::LegendPosition_PAGE_END;
+ eExpansion = css::chart::ChartLegendExpansion_WIDE;
+ break;
+ default:
+ assert(false);
+ }
+
+ xLegendProp->setPropertyValue("AnchorPosition", css::uno::Any(eLegendPos));
+ xLegendProp->setPropertyValue("Expansion", css::uno::Any(eExpansion));
+ xLegendProp->setPropertyValue("RelativePosition", uno::Any());
+}
+
+}
+
+ChartElementsPanel::ChartElementsPanel(
+ weld::Widget* pParent, ChartController* pController)
+ : PanelLayout(pParent, "ChartElementsPanel", "modules/schart/ui/sidebarelements.ui")
+ , mxCBTitle(m_xBuilder->weld_check_button("checkbutton_title"))
+ , mxEditTitle(m_xBuilder->weld_entry("edit_title"))
+ , mxCBSubtitle(m_xBuilder->weld_check_button("checkbutton_subtitle"))
+ , mxEditSubtitle(m_xBuilder->weld_entry("edit_subtitle"))
+ , mxCBXAxis(m_xBuilder->weld_check_button("checkbutton_x_axis"))
+ , mxCBXAxisTitle(m_xBuilder->weld_check_button("checkbutton_x_axis_title"))
+ , mxCBYAxis(m_xBuilder->weld_check_button("checkbutton_y_axis"))
+ , mxCBYAxisTitle(m_xBuilder->weld_check_button("checkbutton_y_axis_title"))
+ , mxCBZAxis(m_xBuilder->weld_check_button("checkbutton_z_axis"))
+ , mxCBZAxisTitle(m_xBuilder->weld_check_button("checkbutton_z_axis_title"))
+ , mxCB2ndXAxis(m_xBuilder->weld_check_button("checkbutton_2nd_x_axis"))
+ , mxCB2ndXAxisTitle(m_xBuilder->weld_check_button("checkbutton_2nd_x_axis_title"))
+ , mxCB2ndYAxis(m_xBuilder->weld_check_button("checkbutton_2nd_y_axis"))
+ , mxCB2ndYAxisTitle(m_xBuilder->weld_check_button("checkbutton_2nd_y_axis_title"))
+ , mxCBLegend(m_xBuilder->weld_check_button("checkbutton_legend"))
+ , mxCBLegendNoOverlay(m_xBuilder->weld_check_button("checkbutton_no_overlay"))
+ , mxCBGridVerticalMajor(m_xBuilder->weld_check_button("checkbutton_gridline_vertical_major"))
+ , mxCBGridHorizontalMajor(m_xBuilder->weld_check_button("checkbutton_gridline_horizontal_major"))
+ , mxCBGridVerticalMinor(m_xBuilder->weld_check_button("checkbutton_gridline_vertical_minor"))
+ , mxCBGridHorizontalMinor(m_xBuilder->weld_check_button("checkbutton_gridline_horizontal_minor"))
+ , mxTextTitle(m_xBuilder->weld_label("text_title"))
+ , mxTextSubTitle(m_xBuilder->weld_label("text_subtitle"))
+ , mxLBAxis(m_xBuilder->weld_label("label_axes"))
+ , mxLBGrid(m_xBuilder->weld_label("label_gri"))
+ , mxLBLegendPosition(m_xBuilder->weld_combo_box("comboboxtext_legend"))
+ , mxBoxLegend(m_xBuilder->weld_widget("box_legend"))
+ , mxModel(pController->getChartModel())
+ , mxListener(new ChartSidebarModifyListener(this))
+ , mbModelValid(true)
+{
+ maTextTitle = mxTextTitle->get_label();
+ maTextSubTitle = mxTextSubTitle->get_label();
+
+ Initialize();
+}
+
+ChartElementsPanel::~ChartElementsPanel()
+{
+ doUpdateModel(nullptr);
+
+ mxCBTitle.reset();
+ mxEditTitle.reset();
+ mxCBSubtitle.reset();
+ mxEditSubtitle.reset();
+ mxCBXAxis.reset();
+ mxCBXAxisTitle.reset();
+ mxCBYAxis.reset();
+ mxCBYAxisTitle.reset();
+ mxCBZAxis.reset();
+ mxCBZAxisTitle.reset();
+ mxCB2ndXAxis.reset();
+ mxCB2ndXAxisTitle.reset();
+ mxCB2ndYAxis.reset();
+ mxCB2ndYAxisTitle.reset();
+ mxCBLegend.reset();
+ mxCBLegendNoOverlay.reset();
+ mxCBGridVerticalMajor.reset();
+ mxCBGridHorizontalMajor.reset();
+ mxCBGridVerticalMinor.reset();
+ mxCBGridHorizontalMinor.reset();
+
+ mxLBLegendPosition.reset();
+ mxBoxLegend.reset();
+
+ mxLBAxis.reset();
+ mxLBGrid.reset();
+
+ mxTextTitle.reset();
+ mxTextSubTitle.reset();
+}
+
+void ChartElementsPanel::Initialize()
+{
+ mxModel->addModifyListener(mxListener);
+ updateData();
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, ChartElementsPanel, CheckBoxHdl);
+ mxCBTitle->connect_toggled(aLink);
+ mxCBSubtitle->connect_toggled(aLink);
+ mxCBXAxis->connect_toggled(aLink);
+ mxCBXAxisTitle->connect_toggled(aLink);
+ mxCBYAxis->connect_toggled(aLink);
+ mxCBYAxisTitle->connect_toggled(aLink);
+ mxCBZAxis->connect_toggled(aLink);
+ mxCBZAxisTitle->connect_toggled(aLink);
+ mxCB2ndXAxis->connect_toggled(aLink);
+ mxCB2ndXAxisTitle->connect_toggled(aLink);
+ mxCB2ndYAxis->connect_toggled(aLink);
+ mxCB2ndYAxisTitle->connect_toggled(aLink);
+ mxCBLegend->connect_toggled(aLink);
+ mxCBLegendNoOverlay->connect_toggled(aLink);
+ mxCBGridVerticalMajor->connect_toggled(aLink);
+ mxCBGridHorizontalMajor->connect_toggled(aLink);
+ mxCBGridVerticalMinor->connect_toggled(aLink);
+ mxCBGridHorizontalMinor->connect_toggled(aLink);
+
+ mxLBLegendPosition->connect_changed(LINK(this, ChartElementsPanel, LegendPosHdl));
+
+ Link<weld::Entry&, void> aEditLink = LINK(this, ChartElementsPanel, EditHdl);
+ mxEditTitle->connect_changed(aEditLink);
+ mxEditSubtitle->connect_changed(aEditLink);
+}
+
+namespace {
+
+rtl::Reference<ChartType> getChartType(const rtl::Reference<ChartModel>& xModel)
+{
+ rtl::Reference<Diagram > xDiagram = xModel->getFirstChartDiagram();
+ if (!xDiagram.is())
+ return nullptr;
+
+ const std::vector<rtl::Reference<BaseCoordinateSystem>> & xCooSysSequence(xDiagram->getBaseCoordinateSystems());
+
+ if (xCooSysSequence.empty())
+ return nullptr;
+
+ const std::vector<rtl::Reference<ChartType>> & xChartTypeSequence(xCooSysSequence[0]->getChartTypes2());
+
+ if (xChartTypeSequence.empty())
+ return nullptr;
+
+ return xChartTypeSequence[0];
+}
+
+}
+
+void ChartElementsPanel::updateData()
+{
+ if (!mbModelValid)
+ return;
+
+ rtl::Reference< Diagram > xDiagram(ChartModelHelper::findDiagram(mxModel));
+ sal_Int32 nDimension = DiagramHelper::getDimension(xDiagram);
+ SolarMutexGuard aGuard;
+
+ mxCBLegend->set_active(isLegendVisible(mxModel));
+ mxCBLegendNoOverlay->set_sensitive(isLegendVisible(mxModel));
+ mxCBLegendNoOverlay->set_active(!isLegendOverlay(mxModel));
+ mxBoxLegend->set_sensitive(isLegendVisible(mxModel));
+
+ bool hasTitle = isTitleVisible(mxModel, TitleHelper::MAIN_TITLE);
+ mxCBTitle->set_active(hasTitle);
+
+ OUString title = mxEditTitle->get_text();
+ OUString newTitle = TitleHelper::getCompleteString(TitleHelper::getTitle(TitleHelper::MAIN_TITLE, mxModel));
+ if (title != newTitle)
+ mxEditTitle->set_text(newTitle);
+ if (mxEditTitle->get_sensitive() != hasTitle)
+ mxEditTitle->set_sensitive(hasTitle);
+
+ bool hasSubtitle = isTitleVisible(mxModel, TitleHelper::SUB_TITLE);
+ mxCBSubtitle->set_active(hasSubtitle);
+
+ OUString subtitle = mxEditSubtitle->get_text();
+ OUString newSubtitle = TitleHelper::getCompleteString(TitleHelper::getTitle(TitleHelper::SUB_TITLE, mxModel));
+ if (subtitle != newSubtitle)
+ mxEditSubtitle->set_text(newSubtitle);
+ if (mxEditSubtitle->get_sensitive() != hasSubtitle)
+ mxEditSubtitle->set_sensitive(hasSubtitle);
+
+ mxCBXAxisTitle->set_active(isTitleVisible(mxModel, TitleHelper::X_AXIS_TITLE));
+ mxCBYAxisTitle->set_active(isTitleVisible(mxModel, TitleHelper::Y_AXIS_TITLE));
+ mxCBZAxisTitle->set_active(isTitleVisible(mxModel, TitleHelper::Z_AXIS_TITLE));
+ mxCB2ndXAxisTitle->set_active(isTitleVisible(mxModel, TitleHelper::SECONDARY_X_AXIS_TITLE));
+ mxCB2ndYAxisTitle->set_active(isTitleVisible(mxModel, TitleHelper::SECONDARY_Y_AXIS_TITLE));
+ mxCBGridVerticalMajor->set_active(isGridVisible(mxModel, GridType::VERT_MAJOR));
+ mxCBGridHorizontalMajor->set_active(isGridVisible(mxModel, GridType::HOR_MAJOR));
+ mxCBGridVerticalMinor->set_active(isGridVisible(mxModel, GridType::VERT_MINOR));
+ mxCBGridHorizontalMinor->set_active(isGridVisible(mxModel, GridType::HOR_MINOR));
+ mxCBXAxis->set_active(isAxisVisible(mxModel, AxisType::X_MAIN));
+ mxCBYAxis->set_active(isAxisVisible(mxModel, AxisType::Y_MAIN));
+ mxCBZAxis->set_active(isAxisVisible(mxModel, AxisType::Z_MAIN));
+ mxCB2ndXAxis->set_active(isAxisVisible(mxModel, AxisType::X_SECOND));
+ mxCB2ndYAxis->set_active(isAxisVisible(mxModel, AxisType::Y_SECOND));
+
+ bool bSupportsMainAxis = ChartTypeHelper::isSupportingMainAxis(
+ getChartType(mxModel), 0, 0);
+ if (bSupportsMainAxis)
+ {
+ mxCBXAxis->show();
+ mxCBYAxis->show();
+ mxCBZAxis->show();
+ mxCBXAxisTitle->show();
+ mxCBYAxisTitle->show();
+ mxCBZAxisTitle->show();
+ mxCBGridVerticalMajor->show();
+ mxCBGridVerticalMinor->show();
+ mxCBGridHorizontalMajor->show();
+ mxCBGridHorizontalMinor->show();
+ mxLBAxis->show();
+ mxLBGrid->show();
+ }
+ else
+ {
+ mxCBXAxis->hide();
+ mxCBYAxis->hide();
+ mxCBZAxis->hide();
+ mxCBXAxisTitle->hide();
+ mxCBYAxisTitle->hide();
+ mxCBZAxisTitle->hide();
+ mxCBGridVerticalMajor->hide();
+ mxCBGridVerticalMinor->hide();
+ mxCBGridHorizontalMajor->hide();
+ mxCBGridHorizontalMinor->hide();
+ mxLBAxis->hide();
+ mxLBGrid->hide();
+ }
+
+ if (nDimension == 3)
+ {
+ mxCBZAxis->set_sensitive(true);
+ mxCBZAxisTitle->set_sensitive(true);
+ }
+ else
+ {
+ mxCBZAxis->set_sensitive(false);
+ mxCBZAxisTitle->set_sensitive(false);
+ }
+
+ mxLBLegendPosition->set_active(getLegendPos(mxModel));
+}
+
+std::unique_ptr<PanelLayout> ChartElementsPanel::Create (
+ weld::Widget* pParent,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw lang::IllegalArgumentException("no parent Window given to ChartElementsPanel::Create", nullptr, 0);
+ return std::make_unique<ChartElementsPanel>(pParent, pController);
+}
+
+void ChartElementsPanel::DataChanged(const DataChangedEvent& rEvent)
+{
+ PanelLayout::DataChanged(rEvent);
+ updateData();
+}
+
+void ChartElementsPanel::HandleContextChange(
+ const vcl::EnumContext& rContext)
+{
+ if(maContext == rContext)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ maContext = rContext;
+ updateData();
+}
+
+void ChartElementsPanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartElementsPanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxListener);
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ mxModel->addModifyListener(mxListener);
+}
+
+void ChartElementsPanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+IMPL_LINK(ChartElementsPanel, CheckBoxHdl, weld::Toggleable&, rCheckBox, void)
+{
+ bool bChecked = rCheckBox.get_active();
+ if (&rCheckBox == mxCBTitle.get())
+ setTitleVisible(TitleHelper::MAIN_TITLE, bChecked);
+ else if (&rCheckBox == mxCBSubtitle.get())
+ setTitleVisible(TitleHelper::SUB_TITLE, bChecked);
+ else if (&rCheckBox == mxCBXAxis.get())
+ setAxisVisible(mxModel, AxisType::X_MAIN, bChecked);
+ else if (&rCheckBox == mxCBXAxisTitle.get())
+ setTitleVisible(TitleHelper::X_AXIS_TITLE, bChecked);
+ else if (&rCheckBox == mxCBYAxis.get())
+ setAxisVisible(mxModel, AxisType::Y_MAIN, bChecked);
+ else if (&rCheckBox == mxCBYAxisTitle.get())
+ setTitleVisible(TitleHelper::Y_AXIS_TITLE, bChecked);
+ else if (&rCheckBox == mxCBZAxis.get())
+ setAxisVisible(mxModel, AxisType::Z_MAIN, bChecked);
+ else if (&rCheckBox == mxCBZAxisTitle.get())
+ setTitleVisible(TitleHelper::Z_AXIS_TITLE, bChecked);
+ else if (&rCheckBox == mxCB2ndXAxis.get())
+ setAxisVisible(mxModel, AxisType::X_SECOND, bChecked);
+ else if (&rCheckBox == mxCB2ndXAxisTitle.get())
+ setTitleVisible(TitleHelper::SECONDARY_X_AXIS_TITLE, bChecked);
+ else if (&rCheckBox == mxCB2ndYAxis.get())
+ setAxisVisible(mxModel, AxisType::Y_SECOND, bChecked);
+ else if (&rCheckBox == mxCB2ndYAxisTitle.get())
+ setTitleVisible(TitleHelper::SECONDARY_Y_AXIS_TITLE, bChecked);
+ else if (&rCheckBox == mxCBLegend.get())
+ {
+ mxBoxLegend->set_sensitive(bChecked);
+ mxCBLegendNoOverlay->set_sensitive(bChecked);
+ setLegendVisible(mxModel, bChecked);
+ }
+ else if (&rCheckBox == mxCBLegendNoOverlay.get())
+ setLegendOverlay(mxModel, !bChecked);
+ else if (&rCheckBox == mxCBGridVerticalMajor.get())
+ setGridVisible(mxModel, GridType::VERT_MAJOR, bChecked);
+ else if (&rCheckBox == mxCBGridHorizontalMajor.get())
+ setGridVisible(mxModel, GridType::HOR_MAJOR, bChecked);
+ else if (&rCheckBox == mxCBGridVerticalMinor.get())
+ setGridVisible(mxModel, GridType::VERT_MINOR, bChecked);
+ else if (&rCheckBox == mxCBGridHorizontalMinor.get())
+ setGridVisible(mxModel, GridType::HOR_MINOR, bChecked);
+
+ updateData();
+}
+
+IMPL_LINK(ChartElementsPanel, EditHdl, weld::Entry&, rEdit, void)
+{
+ // title or subtitle?
+ TitleHelper::eTitleType aTitleType = TitleHelper::MAIN_TITLE;
+ if (&rEdit == mxEditSubtitle.get())
+ aTitleType = TitleHelper::SUB_TITLE;
+
+ // set it
+ OUString aText(rEdit.get_text());
+ TitleHelper::setCompleteString(aText, TitleHelper::getTitle(aTitleType, mxModel), comphelper::getProcessComponentContext());
+}
+
+IMPL_LINK_NOARG(ChartElementsPanel, LegendPosHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = mxLBLegendPosition->get_active();
+ setLegendPos(mxModel, nPos);
+}
+
+void ChartElementsPanel::setTitleVisible(TitleHelper::eTitleType eTitle, bool bVisible)
+{
+ if (bVisible)
+ {
+ OUString aText = eTitle == TitleHelper::SUB_TITLE ? maTextSubTitle : maTextTitle;
+ TitleHelper::createOrShowTitle(eTitle, aText, mxModel, comphelper::getProcessComponentContext());
+ }
+ else
+ {
+ TitleHelper::hideTitle(eTitle, mxModel);
+ }
+}
+
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartElementsPanel.hxx b/chart2/source/controller/sidebar/ChartElementsPanel.hxx
new file mode 100644
index 000000000..07c7ee19c
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartElementsPanel.hxx
@@ -0,0 +1,116 @@
+/* -*- 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/sidebar/IContextChangeReceiver.hxx>
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/EnumContext.hxx>
+#include "ChartSidebarModifyListener.hxx"
+#include <TitleHelper.hxx>
+
+namespace com::sun::star::util { class XModifyListener; }
+
+namespace chart {
+
+class ChartController;
+
+namespace sidebar {
+
+class ChartElementsPanel : public PanelLayout,
+ public ::sfx2::sidebar::IContextChangeReceiver,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ ChartController* pController);
+
+ virtual void DataChanged(
+ const DataChangedEvent& rEvent) override;
+
+ virtual void HandleContextChange(
+ const vcl::EnumContext& rContext) override;
+
+ // constructor/destructor
+ ChartElementsPanel(
+ weld::Widget* pParent,
+ ChartController* pController);
+
+ virtual ~ChartElementsPanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+private:
+ //ui controls
+ std::unique_ptr<weld::CheckButton> mxCBTitle;
+ std::unique_ptr<weld::Entry> mxEditTitle;
+ std::unique_ptr<weld::CheckButton> mxCBSubtitle;
+ std::unique_ptr<weld::Entry> mxEditSubtitle;
+ std::unique_ptr<weld::CheckButton> mxCBXAxis;
+ std::unique_ptr<weld::CheckButton> mxCBXAxisTitle;
+ std::unique_ptr<weld::CheckButton> mxCBYAxis;
+ std::unique_ptr<weld::CheckButton> mxCBYAxisTitle;
+ std::unique_ptr<weld::CheckButton> mxCBZAxis;
+ std::unique_ptr<weld::CheckButton> mxCBZAxisTitle;
+ std::unique_ptr<weld::CheckButton> mxCB2ndXAxis;
+ std::unique_ptr<weld::CheckButton> mxCB2ndXAxisTitle;
+ std::unique_ptr<weld::CheckButton> mxCB2ndYAxis;
+ std::unique_ptr<weld::CheckButton> mxCB2ndYAxisTitle;
+ std::unique_ptr<weld::CheckButton> mxCBLegend;
+ std::unique_ptr<weld::CheckButton> mxCBLegendNoOverlay;
+ std::unique_ptr<weld::CheckButton> mxCBGridVerticalMajor;
+ std::unique_ptr<weld::CheckButton> mxCBGridHorizontalMajor;
+ std::unique_ptr<weld::CheckButton> mxCBGridVerticalMinor;
+ std::unique_ptr<weld::CheckButton> mxCBGridHorizontalMinor;
+ std::unique_ptr<weld::Label> mxTextTitle;
+ std::unique_ptr<weld::Label> mxTextSubTitle;
+ std::unique_ptr<weld::Label> mxLBAxis;
+ std::unique_ptr<weld::Label> mxLBGrid;
+
+ std::unique_ptr<weld::ComboBox> mxLBLegendPosition;
+ std::unique_ptr<weld::Widget> mxBoxLegend;
+
+ vcl::EnumContext maContext;
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+
+ bool mbModelValid;
+
+ OUString maTextTitle;
+ OUString maTextSubTitle;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ void setTitleVisible(TitleHelper::eTitleType eTitle, bool bVisible);
+
+ DECL_LINK(CheckBoxHdl, weld::Toggleable&, void);
+ DECL_LINK(EditHdl, weld::Entry&, void);
+ DECL_LINK(LegendPosHdl, weld::ComboBox&, void);
+};
+
+} } // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartErrorBarPanel.cxx b/chart2/source/controller/sidebar/ChartErrorBarPanel.cxx
new file mode 100644
index 000000000..e86fdf0fe
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartErrorBarPanel.cxx
@@ -0,0 +1,425 @@
+/* -*- 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/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include "ChartErrorBarPanel.hxx"
+#include <ChartController.hxx>
+#include <ChartModel.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+
+using namespace css;
+using namespace css::uno;
+
+namespace chart::sidebar {
+
+namespace {
+
+enum class ErrorBarDirection
+{
+ POSITIVE,
+ NEGATIVE
+};
+
+css::uno::Reference<css::beans::XPropertySet> getErrorBarPropSet(
+ const rtl::Reference<::chart::ChartModel>& xModel, const OUString& rCID)
+{
+ return ObjectIdentifier::getObjectPropertySet(rCID, xModel);
+}
+
+bool showPositiveError(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return false;
+
+ css::uno::Any aAny = xPropSet->getPropertyValue("ShowPositiveError");
+
+ if (!aAny.hasValue())
+ return false;
+
+ bool bShow = false;
+ aAny >>= bShow;
+ return bShow;
+}
+
+bool showNegativeError(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return false;
+
+ css::uno::Any aAny = xPropSet->getPropertyValue("ShowNegativeError");
+
+ if (!aAny.hasValue())
+ return false;
+
+ bool bShow = false;
+ aAny >>= bShow;
+ return bShow;
+}
+
+void setShowPositiveError(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, bool bShow)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return;
+
+ xPropSet->setPropertyValue("ShowPositiveError", css::uno::Any(bShow));
+}
+
+void setShowNegativeError(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, bool bShow)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return;
+
+ xPropSet->setPropertyValue("ShowNegativeError", css::uno::Any(bShow));
+}
+
+struct ErrorBarTypeMap
+{
+ sal_Int32 nPos;
+ sal_Int32 nApi;
+};
+
+ErrorBarTypeMap const aErrorBarType[] = {
+ { 0, css::chart::ErrorBarStyle::ABSOLUTE },
+ { 1, css::chart::ErrorBarStyle::RELATIVE },
+ { 2, css::chart::ErrorBarStyle::FROM_DATA },
+ { 3, css::chart::ErrorBarStyle::STANDARD_DEVIATION },
+ { 4, css::chart::ErrorBarStyle::STANDARD_ERROR },
+ { 5, css::chart::ErrorBarStyle::VARIANCE},
+ { 6, css::chart::ErrorBarStyle::ERROR_MARGIN },
+};
+
+sal_Int32 getTypePos(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return 0;
+
+ css::uno::Any aAny = xPropSet->getPropertyValue("ErrorBarStyle");
+
+ if (!aAny.hasValue())
+ return 0;
+
+ sal_Int32 nApi = 0;
+ aAny >>= nApi;
+
+ for (ErrorBarTypeMap const & i : aErrorBarType)
+ {
+ if (i.nApi == nApi)
+ return i.nPos;
+ }
+
+ return 0;
+}
+
+void setTypePos(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, sal_Int32 nPos)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return;
+
+ sal_Int32 nApi = 0;
+ for (ErrorBarTypeMap const & i : aErrorBarType)
+ {
+ if (i.nPos == nPos)
+ nApi = i.nApi;
+ }
+
+ xPropSet->setPropertyValue("ErrorBarStyle", css::uno::Any(nApi));
+}
+
+double getValue(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, ErrorBarDirection eDir)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return 0;
+
+ OUString aName = "PositiveError";
+ if (eDir == ErrorBarDirection::NEGATIVE)
+ aName = "NegativeError";
+
+ css::uno::Any aAny = xPropSet->getPropertyValue(aName);
+
+ if (!aAny.hasValue())
+ return 0;
+
+ double nVal = 0;
+ aAny >>= nVal;
+
+ return nVal;
+}
+
+void setValue(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, double nVal, ErrorBarDirection eDir)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getErrorBarPropSet(xModel, rCID);
+
+ if (!xPropSet.is())
+ return;
+
+ OUString aName = "PositiveError";
+ if (eDir == ErrorBarDirection::NEGATIVE)
+ aName = "NegativeError";
+
+ xPropSet->setPropertyValue(aName, css::uno::Any(nVal));
+}
+
+OUString getCID(const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ uno::Any aAny = xSelectionSupplier->getSelection();
+ assert(aAny.hasValue());
+ OUString aCID;
+ aAny >>= aCID;
+#if defined DBG_UTIL && !defined NDEBUG
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType != OBJECTTYPE_DATA_ERRORS_X &&
+ eType != OBJECTTYPE_DATA_ERRORS_Y &&
+ eType != OBJECTTYPE_DATA_ERRORS_Z)
+ SAL_WARN("chart2","Selected item is not an error bar");
+
+#endif
+
+ return aCID;
+}
+
+}
+
+ChartErrorBarPanel::ChartErrorBarPanel(weld::Widget* pParent, ChartController* pController)
+ : PanelLayout(pParent, "ChartErrorBarPanel", "modules/schart/ui/sidebarerrorbar.ui")
+ , mxRBPosAndNeg(m_xBuilder->weld_radio_button("radiobutton_positive_negative"))
+ , mxRBPos(m_xBuilder->weld_radio_button("radiobutton_positive"))
+ , mxRBNeg(m_xBuilder->weld_radio_button("radiobutton_negative"))
+ , mxLBType(m_xBuilder->weld_combo_box("comboboxtext_type"))
+ , mxMFPos(m_xBuilder->weld_spin_button("spinbutton_pos"))
+ , mxMFNeg(m_xBuilder->weld_spin_button("spinbutton_neg"))
+ , mxModel(pController->getChartModel())
+ , mxListener(new ChartSidebarModifyListener(this))
+ , mbModelValid(true)
+{
+ Initialize();
+}
+
+ChartErrorBarPanel::~ChartErrorBarPanel()
+{
+ doUpdateModel(nullptr);
+
+ mxRBPosAndNeg.reset();
+ mxRBPos.reset();
+ mxRBNeg.reset();
+
+ mxLBType.reset();
+
+ mxMFPos.reset();
+ mxMFNeg.reset();
+}
+
+void ChartErrorBarPanel::Initialize()
+{
+ mxModel->addModifyListener(mxListener);
+ mxRBNeg->set_active(false);
+ mxRBPos->set_active(false);
+ mxRBPosAndNeg->set_active(false);
+
+ updateData();
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, ChartErrorBarPanel, RadioBtnHdl);
+ mxRBPosAndNeg->connect_toggled(aLink);
+ mxRBPos->connect_toggled(aLink);
+ mxRBNeg->connect_toggled(aLink);
+
+ mxLBType->connect_changed(LINK(this, ChartErrorBarPanel, ListBoxHdl));
+
+ Link<weld::SpinButton&,void> aLink2 = LINK(this, ChartErrorBarPanel, NumericFieldHdl);
+ mxMFPos->connect_value_changed(aLink2);
+ mxMFNeg->connect_value_changed(aLink2);
+}
+
+void ChartErrorBarPanel::updateData()
+{
+ if (!mbModelValid)
+ return;
+
+ OUString aCID = getCID(mxModel);
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType != OBJECTTYPE_DATA_ERRORS_X &&
+ eType != OBJECTTYPE_DATA_ERRORS_Y &&
+ eType != OBJECTTYPE_DATA_ERRORS_Z)
+ return;
+
+ bool bPos = showPositiveError(mxModel, aCID);
+ bool bNeg = showNegativeError(mxModel, aCID);
+
+ SolarMutexGuard aGuard;
+
+ if (bPos && bNeg)
+ mxRBPosAndNeg->set_active(true);
+ else if (bPos)
+ mxRBPos->set_active(true);
+ else if (bNeg)
+ mxRBNeg->set_active(true);
+
+ sal_Int32 nTypePos = getTypePos(mxModel, aCID);
+ mxLBType->set_active(nTypePos);
+
+ if (nTypePos <= 1)
+ {
+ if (bPos)
+ mxMFPos->set_sensitive(true);
+ else
+ mxMFPos->set_sensitive(false);
+
+ if (bNeg)
+ mxMFNeg->set_sensitive(true);
+ else
+ mxMFNeg->set_sensitive(false);
+
+ double nValPos = getValue(mxModel, aCID, ErrorBarDirection::POSITIVE);
+ double nValNeg = getValue(mxModel, aCID, ErrorBarDirection::NEGATIVE);
+
+ mxMFPos->set_value(nValPos);
+ mxMFNeg->set_value(nValNeg);
+ }
+ else
+ {
+ mxMFPos->set_sensitive(false);
+ mxMFNeg->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<PanelLayout> ChartErrorBarPanel::Create (
+ weld::Widget* pParent,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw lang::IllegalArgumentException("no parent Window given to ChartErrorBarPanel::Create", nullptr, 0);
+ return std::make_unique<ChartErrorBarPanel>(pParent, pController);
+}
+
+void ChartErrorBarPanel::DataChanged(const DataChangedEvent& rEvent)
+{
+ PanelLayout::DataChanged(rEvent);
+ updateData();
+}
+
+void ChartErrorBarPanel::HandleContextChange(
+ const vcl::EnumContext& )
+{
+ updateData();
+}
+
+void ChartErrorBarPanel::NotifyItemUpdate(
+ sal_uInt16 /*nSID*/,
+ SfxItemState /*eState*/,
+ const SfxPoolItem* /*pState*/ )
+{
+}
+
+void ChartErrorBarPanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartErrorBarPanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxListener);
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ mxModel->addModifyListener(mxListener);
+}
+
+void ChartErrorBarPanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+IMPL_LINK_NOARG(ChartErrorBarPanel, RadioBtnHdl, weld::Toggleable&, void)
+{
+ OUString aCID = getCID(mxModel);
+ bool bPos = mxRBPosAndNeg->get_active() || mxRBPos->get_active();
+ bool bNeg = mxRBPosAndNeg->get_active() || mxRBNeg->get_active();
+
+ setShowPositiveError(mxModel, aCID, bPos);
+ setShowNegativeError(mxModel, aCID, bNeg);
+}
+
+IMPL_LINK_NOARG(ChartErrorBarPanel, ListBoxHdl, weld::ComboBox&, void)
+{
+ OUString aCID = getCID(mxModel);
+ sal_Int32 nPos = mxLBType->get_active();
+
+ setTypePos(mxModel, aCID, nPos);
+}
+
+IMPL_LINK(ChartErrorBarPanel, NumericFieldHdl, weld::SpinButton&, rMetricField, void)
+{
+ OUString aCID = getCID(mxModel);
+ double nVal = rMetricField.get_value();
+ if (&rMetricField == mxMFPos.get())
+ setValue(mxModel, aCID, nVal, ErrorBarDirection::POSITIVE);
+ else if (&rMetricField == mxMFNeg.get())
+ setValue(mxModel, aCID, nVal, ErrorBarDirection::NEGATIVE);
+}
+
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartErrorBarPanel.hxx b/chart2/source/controller/sidebar/ChartErrorBarPanel.hxx
new file mode 100644
index 000000000..1613006b7
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartErrorBarPanel.hxx
@@ -0,0 +1,91 @@
+/* -*- 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/sidebar/ControllerItem.hxx>
+#include <sfx2/sidebar/IContextChangeReceiver.hxx>
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <sfx2/sidebar/PanelLayout.hxx>
+#include "ChartSidebarModifyListener.hxx"
+
+namespace com::sun::star::util { class XModifyListener; }
+
+namespace chart {
+
+class ChartController;
+class ChartModel;
+
+namespace sidebar {
+
+class ChartErrorBarPanel : public PanelLayout,
+ public ::sfx2::sidebar::IContextChangeReceiver,
+ public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ ChartController* pController);
+
+ virtual void DataChanged(
+ const DataChangedEvent& rEvent) override;
+
+ virtual void HandleContextChange(
+ const vcl::EnumContext& rContext) override;
+
+ virtual void NotifyItemUpdate(
+ const sal_uInt16 nSId,
+ const SfxItemState eState,
+ const SfxPoolItem* pState) override;
+
+ virtual void GetControlState(
+ const sal_uInt16 /*nSId*/,
+ boost::property_tree::ptree& /*rState*/) override {};
+
+ // constructor/destructor
+ ChartErrorBarPanel(
+ weld::Widget* pParent,
+ ChartController* pController);
+ virtual ~ChartErrorBarPanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+private:
+ //ui controls
+ std::unique_ptr<weld::RadioButton> mxRBPosAndNeg;
+ std::unique_ptr<weld::RadioButton> mxRBPos;
+ std::unique_ptr<weld::RadioButton> mxRBNeg;
+
+ std::unique_ptr<weld::ComboBox> mxLBType;
+
+ std::unique_ptr<weld::SpinButton> mxMFPos;
+ std::unique_ptr<weld::SpinButton> mxMFNeg;
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+
+ bool mbModelValid;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ DECL_LINK(RadioBtnHdl, weld::Toggleable&, void);
+ DECL_LINK(ListBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(NumericFieldHdl, weld::SpinButton&, void);
+};
+
+} } // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartLinePanel.cxx b/chart2/source/controller/sidebar/ChartLinePanel.cxx
new file mode 100644
index 000000000..d9da9a298
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartLinePanel.cxx
@@ -0,0 +1,293 @@
+/* -*- 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 "ChartLinePanel.hxx"
+
+#include <ChartController.hxx>
+#include <ChartModel.hxx>
+
+#include <svx/xlnwtit.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlntrit.hxx>
+
+#include <svx/linectrl.hxx>
+#include <svx/tbcontrl.hxx>
+#include <sfx2/weldutils.hxx>
+#include <vcl/svapp.hxx>
+
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/chart2/XDiagram.hpp>
+
+#include <comphelper/lok.hxx>
+#include <sfx2/viewsh.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+
+namespace chart::sidebar {
+
+namespace {
+
+SvxLineStyleToolBoxControl* getLineStyleToolBoxControl(const ToolbarUnoDispatcher& rToolBoxColor)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController = rToolBoxColor.GetControllerForCommand(".uno:XLineStyle");
+ SvxLineStyleToolBoxControl* pToolBoxLineStyleControl = dynamic_cast<SvxLineStyleToolBoxControl*>(xController.get());
+ return pToolBoxLineStyleControl;
+}
+
+SvxColorToolBoxControl* getColorToolBoxControl(const ToolbarUnoDispatcher& rToolBoxLineStyle)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController = rToolBoxLineStyle.GetControllerForCommand(".uno:XLineColor");
+ SvxColorToolBoxControl* pToolBoxColorControl = dynamic_cast<SvxColorToolBoxControl*>(xController.get());
+ return pToolBoxColorControl;
+}
+
+OUString getCID(const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ css::uno::Any aAny = xSelectionSupplier->getSelection();
+ if (!aAny.hasValue())
+ {
+ xSelectionSupplier->select(css::uno::Any(OUString("CID/Page=")));
+ aAny = xSelectionSupplier->getSelection();
+ }
+
+ OUString aCID;
+ aAny >>= aCID;
+
+ return aCID;
+}
+
+css::uno::Reference<css::beans::XPropertySet> getPropSet(
+ const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ OUString aCID = getCID(xModel);
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ ObjectIdentifier::getObjectPropertySet(aCID, xModel);
+
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType == OBJECTTYPE_DIAGRAM)
+ {
+ css::uno::Reference<css::chart2::XDiagram> xDiagram(
+ xPropSet, css::uno::UNO_QUERY);
+ if (!xDiagram.is())
+ return xPropSet;
+
+ xPropSet.set(xDiagram->getWall());
+ }
+
+ return xPropSet;
+}
+
+class PreventUpdate
+{
+public:
+ explicit PreventUpdate(bool& bUpdate):
+ mbUpdate(bUpdate)
+ {
+ mbUpdate = false;
+ }
+
+ ~PreventUpdate()
+ {
+ mbUpdate = true;
+ }
+
+private:
+ bool& mbUpdate;
+};
+
+}
+
+std::unique_ptr<PanelLayout> ChartLinePanel::Create(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw css::lang::IllegalArgumentException("no parent Window given to ChartAxisPanel::Create", nullptr, 0);
+ if (!rxFrame.is())
+ throw css::lang::IllegalArgumentException("no XFrame given to ChartAxisPanel::Create", nullptr, 1);
+
+ return std::make_unique<ChartLinePanel>(pParent, rxFrame, pController);
+}
+
+ChartLinePanel::ChartLinePanel(weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController):
+ svx::sidebar::LinePropertyPanelBase(pParent, rxFrame),
+ mxModel(pController->getChartModel()),
+ mxListener(new ChartSidebarModifyListener(this)),
+ mxSelectionListener(new ChartSidebarSelectionListener(this)),
+ mbUpdate(true),
+ mbModelValid(true),
+ maLineColorWrapper(mxModel, getColorToolBoxControl(*mxColorDispatch), "LineColor"),
+ maLineStyleWrapper(mxModel, getLineStyleToolBoxControl(*mxLineStyleDispatch))
+{
+ disableArrowHead();
+ std::vector<ObjectType> aAcceptedTypes { OBJECTTYPE_PAGE, OBJECTTYPE_DIAGRAM,
+ OBJECTTYPE_DATA_SERIES, OBJECTTYPE_DATA_POINT,
+ OBJECTTYPE_TITLE, OBJECTTYPE_LEGEND, OBJECTTYPE_DATA_CURVE,
+ OBJECTTYPE_DATA_AVERAGE_LINE, OBJECTTYPE_AXIS};
+ mxSelectionListener->setAcceptedTypes(std::move(aAcceptedTypes));
+ Initialize();
+}
+
+ChartLinePanel::~ChartLinePanel()
+{
+ doUpdateModel(nullptr);
+}
+
+void ChartLinePanel::Initialize()
+{
+ mxModel->addModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+
+ SvxColorToolBoxControl* pToolBoxColor = getColorToolBoxControl(*mxColorDispatch);
+ pToolBoxColor->setColorSelectFunction(maLineColorWrapper);
+
+ SvxLineStyleToolBoxControl* pToolBoxLineStyle = getLineStyleToolBoxControl(*mxLineStyleDispatch);
+ pToolBoxLineStyle->setLineStyleSelectFunction(maLineStyleWrapper);
+
+ setMapUnit(MapUnit::Map100thMM);
+ updateData();
+}
+
+void ChartLinePanel::updateData()
+{
+ if (!mbUpdate || !mbModelValid)
+ return;
+
+ SolarMutexGuard aGuard;
+ css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
+ if (!xPropSet.is())
+ return;
+
+ sal_uInt16 nLineTransparence = 0;
+ xPropSet->getPropertyValue("LineTransparence") >>= nLineTransparence;
+ XLineTransparenceItem aLineTransparenceItem(nLineTransparence);
+ updateLineTransparence(false, true, &aLineTransparenceItem);
+
+ sal_uInt32 nWidth = 0;
+ xPropSet->getPropertyValue("LineWidth") >>= nWidth;
+ XLineWidthItem aWidthItem(nWidth);
+ updateLineWidth(false, true, &aWidthItem);
+
+ maLineStyleWrapper.updateData();
+ maLineColorWrapper.updateData();
+}
+
+void ChartLinePanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartLinePanel::selectionChanged(bool bCorrectType)
+{
+ if (bCorrectType)
+ updateData();
+}
+
+void ChartLinePanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
+ mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (oldSelectionSupplier.is()) {
+ oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
+ }
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ maLineStyleWrapper.updateModel(mxModel);
+ maLineColorWrapper.updateModel(mxModel);
+
+ mxModel->addModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+}
+
+void ChartLinePanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+void ChartLinePanel::setLineJoint(const XLineJointItem* pItem)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getPropSet(mxModel);
+
+ if (!xPropSet.is())
+ return;
+
+ PreventUpdate aPreventUpdate(mbUpdate);
+ if (pItem)
+ xPropSet->setPropertyValue("LineJoint", css::uno::Any(pItem->GetValue()));
+}
+
+void ChartLinePanel::setLineCap(const XLineCapItem* /*pItem*/)
+{
+}
+
+void ChartLinePanel::setLineTransparency(const XLineTransparenceItem& rItem)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getPropSet(mxModel);
+
+ if (!xPropSet.is())
+ return;
+
+ PreventUpdate aPreventUpdate(mbUpdate);
+ xPropSet->setPropertyValue("LineTransparence", css::uno::Any(rItem.GetValue()));
+}
+
+void ChartLinePanel::setLineWidth(const XLineWidthItem& rItem)
+{
+ css::uno::Reference<css::beans::XPropertySet> xPropSet =
+ getPropSet(mxModel);
+
+ if (!xPropSet.is())
+ return;
+
+ PreventUpdate aPreventUpdate(mbUpdate);
+ xPropSet->setPropertyValue("LineWidth", css::uno::Any(rItem.GetValue()));
+}
+
+void ChartLinePanel::updateLineWidth(bool bDisabled, bool bSetOrDefault, const SfxPoolItem* pItem)
+{
+ LinePropertyPanelBase::updateLineWidth(bDisabled, bSetOrDefault, pItem);
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (comphelper::LibreOfficeKit::isActive() && pViewShell)
+ {
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
+ (".uno:LineWidth=" + std::to_string(mnWidthCoreValue)).c_str());
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartLinePanel.hxx b/chart2/source/controller/sidebar/ChartLinePanel.hxx
new file mode 100644
index 000000000..10bfd5a4c
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartLinePanel.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/.
+ */
+
+#pragma once
+
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <svx/sidebar/LinePropertyPanelBase.hxx>
+
+#include "ChartSidebarModifyListener.hxx"
+#include "ChartSidebarSelectionListener.hxx"
+#include "ChartColorWrapper.hxx"
+
+class XLineCapItem;
+class XLineDashItem;
+class XLineEndItem;
+class XLineJointItem;
+class XLineStartItem;
+class XLineStyleItem;
+class XLineTransparenceItem;
+class XLineWidthItem;
+
+namespace chart {
+
+class ChartController;
+
+namespace sidebar {
+
+class ChartLinePanel : public svx::sidebar::LinePropertyPanelBase,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent,
+ public ChartSidebarSelectionListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController);
+
+ // constructor/destructor
+ ChartLinePanel(
+ weld::Widget* pParent,
+ const css::uno::Reference<css::frame::XFrame>& rxFrame,
+ ChartController* pController);
+
+ virtual ~ChartLinePanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void selectionChanged(bool bCorrectType) override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+ virtual void setLineWidth(const XLineWidthItem& rItem) override;
+
+protected:
+
+ virtual void setLineTransparency(const XLineTransparenceItem& rItem) override;
+ virtual void setLineJoint(const XLineJointItem* pItem) override;
+ virtual void setLineCap(const XLineCapItem* pItem) override;
+
+ virtual void updateLineWidth(bool bDisabled, bool bSetOrDefault, const SfxPoolItem* pItem) override;
+
+private:
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+ rtl::Reference<ChartSidebarSelectionListener> mxSelectionListener;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ bool mbUpdate;
+ bool mbModelValid;
+ ChartColorWrapper maLineColorWrapper;
+ ChartLineStyleWrapper maLineStyleWrapper;
+};
+
+} } // end of namespace svx::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSeriesPanel.cxx b/chart2/source/controller/sidebar/ChartSeriesPanel.cxx
new file mode 100644
index 000000000..c5b21ed5a
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSeriesPanel.cxx
@@ -0,0 +1,474 @@
+/* -*- 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/chart/ErrorBarStyle.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+
+#include "ChartSeriesPanel.hxx"
+#include <ChartController.hxx>
+#include <ChartModel.hxx>
+#include <ChartType.hxx>
+#include <DataSeries.hxx>
+#include <DataSeriesHelper.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <RegressionCurveHelper.hxx>
+#include <RegressionCurveModel.hxx>
+#include <StatisticsHelper.hxx>
+#include <BaseCoordinateSystem.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace css;
+using namespace css::uno;
+
+namespace chart::sidebar {
+
+namespace {
+
+bool isDataLabelVisible(const rtl::Reference<::chart::ChartModel>& xModel, const OUString& rCID)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return false;
+
+ return DataSeriesHelper::hasDataLabelsAtSeries(xSeries);
+}
+
+void setDataLabelVisible(const rtl::Reference<::chart::ChartModel>& xModel, const OUString& rCID, bool bVisible)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return;
+
+ if (bVisible)
+ DataSeriesHelper::insertDataLabelsToSeriesAndAllPoints(xSeries);
+ else
+ DataSeriesHelper::deleteDataLabelsFromSeriesAndAllPoints(xSeries);
+}
+
+struct LabelPlacementMap
+{
+ sal_Int32 nPos;
+ sal_Int32 nApi;
+};
+
+LabelPlacementMap const aLabelPlacementMap[] = {
+ { 0, css::chart::DataLabelPlacement::TOP },
+ { 1, css::chart::DataLabelPlacement::BOTTOM },
+ { 2, css::chart::DataLabelPlacement::CENTER },
+ { 3, css::chart::DataLabelPlacement::OUTSIDE },
+ { 4, css::chart::DataLabelPlacement::INSIDE },
+ { 5, css::chart::DataLabelPlacement::NEAR_ORIGIN }
+};
+
+sal_Int32 getDataLabelPlacement(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return 0;
+
+ css::uno::Any aAny = xSeries->getPropertyValue("LabelPlacement");
+ if (!aAny.hasValue())
+ return 0;
+
+ sal_Int32 nPlacement = 0;
+ aAny >>= nPlacement;
+
+ for (LabelPlacementMap const & i : aLabelPlacementMap)
+ {
+ if (i.nApi == nPlacement)
+ return i.nPos;
+ }
+
+ return 0;
+}
+
+void setDataLabelPlacement(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, sal_Int32 nPos)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return;
+
+ sal_Int32 nApi = 0;
+ for (LabelPlacementMap const & i : aLabelPlacementMap)
+ {
+ if (i.nPos == nPos)
+ {
+ nApi = i.nApi;
+ break;
+ }
+ }
+
+ xSeries->setPropertyValue("LabelPlacement", css::uno::Any(nApi));
+}
+
+bool isTrendlineVisible(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID)
+{
+ rtl::Reference< DataSeries > xRegressionCurveContainer =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xRegressionCurveContainer.is())
+ return false;
+
+ return xRegressionCurveContainer->getRegressionCurves().hasElements();
+}
+
+void setTrendlineVisible(const rtl::Reference<::chart::ChartModel>&
+ xModel, const OUString& rCID, bool bVisible)
+{
+ rtl::Reference< DataSeries > xRegressionCurveContainer =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xRegressionCurveContainer.is())
+ return;
+
+ if (bVisible)
+ {
+ RegressionCurveHelper::addRegressionCurve(
+ SvxChartRegress::Linear,
+ xRegressionCurveContainer);
+ }
+ else
+ RegressionCurveHelper::removeAllExceptMeanValueLine(
+ xRegressionCurveContainer );
+
+}
+
+bool isErrorBarVisible(const rtl::Reference<::chart::ChartModel>& xModel,
+ const OUString& rCID, bool bYError)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return false;
+
+ return StatisticsHelper::hasErrorBars(xSeries, bYError);
+}
+
+void setErrorBarVisible(const rtl::Reference<::chart::ChartModel>&
+ xModel, const OUString& rCID, bool bYError, bool bVisible)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return;
+
+ if (bVisible)
+ {
+ StatisticsHelper::addErrorBars( xSeries,
+ css::chart::ErrorBarStyle::STANDARD_DEVIATION,
+ bYError);
+ }
+ else
+ {
+ StatisticsHelper::removeErrorBars( xSeries, bYError );
+ }
+}
+
+bool isPrimaryAxis(const rtl::Reference<::chart::ChartModel>&
+ xModel, const OUString& rCID)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return true;
+
+ return DataSeriesHelper::getAttachedAxisIndex(xSeries) == 0;
+}
+
+void setAttachedAxisType(const rtl::Reference<::chart::ChartModel>&
+ xModel, const OUString& rCID, bool bPrimary)
+{
+ const rtl::Reference<DataSeries> xDataSeries = ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xDataSeries.is())
+ return;
+
+ rtl::Reference<Diagram> xDiagram = xModel->getFirstChartDiagram();
+ DiagramHelper::attachSeriesToAxis(bPrimary, xDataSeries, xDiagram, comphelper::getProcessComponentContext());
+}
+
+rtl::Reference<ChartType> getChartType(
+ const rtl::Reference<::chart::ChartModel>& xModel)
+{
+ rtl::Reference<Diagram> xDiagram = xModel->getFirstChartDiagram();
+ const std::vector< rtl::Reference< BaseCoordinateSystem > > & xCooSysSequence( xDiagram->getBaseCoordinateSystems());
+ return xCooSysSequence[0]->getChartTypes2()[0];
+}
+
+OUString getSeriesLabel(const rtl::Reference<::chart::ChartModel>& xModel, const OUString& rCID)
+{
+ rtl::Reference< DataSeries > xSeries =
+ ObjectIdentifier::getDataSeriesForCID(rCID, xModel);
+
+ if (!xSeries.is())
+ return OUString();
+
+ rtl::Reference<ChartType> xChartType = getChartType(xModel);
+ return DataSeriesHelper::getDataSeriesLabel(xSeries, xChartType->getRoleOfSequenceForSeriesLabel());
+}
+
+OUString getCID(const css::uno::Reference<css::frame::XModel>& xModel)
+{
+ css::uno::Reference<css::frame::XController> xController(xModel->getCurrentController());
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (!xSelectionSupplier.is())
+ return OUString();
+
+ uno::Any aAny = xSelectionSupplier->getSelection();
+ if (!aAny.hasValue())
+ return OUString();
+
+ OUString aCID;
+ aAny >>= aCID;
+
+ if (aCID.isEmpty())
+ return OUString();
+
+#if defined DBG_UTIL && !defined NDEBUG
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType != OBJECTTYPE_DATA_SERIES &&
+ eType != OBJECTTYPE_DATA_POINT &&
+ eType != OBJECTTYPE_DATA_CURVE)
+ SAL_WARN("chart2","Selected item is not a chart series");
+#endif
+
+ return aCID;
+}
+
+}
+
+ChartSeriesPanel::ChartSeriesPanel(
+ weld::Widget* pParent,
+ ChartController* pController)
+ : PanelLayout(pParent, "ChartSeriesPanel", "modules/schart/ui/sidebarseries.ui")
+ , mxCBLabel(m_xBuilder->weld_check_button("checkbutton_label"))
+ , mxCBTrendline(m_xBuilder->weld_check_button("checkbutton_trendline"))
+ , mxCBXError(m_xBuilder->weld_check_button("checkbutton_x_error"))
+ , mxCBYError(m_xBuilder->weld_check_button("checkbutton_y_error"))
+ , mxRBPrimaryAxis(m_xBuilder->weld_radio_button("radiobutton_primary_axis"))
+ , mxRBSecondaryAxis(m_xBuilder->weld_radio_button("radiobutton_secondary_axis"))
+ , mxBoxLabelPlacement(m_xBuilder->weld_widget("datalabel_box"))
+ , mxLBLabelPlacement(m_xBuilder->weld_combo_box("comboboxtext_label"))
+ , mxFTSeriesName(m_xBuilder->weld_label("label_series_name"))
+ , mxFTSeriesTemplate(m_xBuilder->weld_label("label_series_tmpl"))
+ , mxModel(pController->getChartModel())
+ , mxListener(new ChartSidebarModifyListener(this))
+ , mxSelectionListener(new ChartSidebarSelectionListener(this, OBJECTTYPE_DATA_SERIES))
+ , mbModelValid(true)
+{
+ Initialize();
+}
+
+ChartSeriesPanel::~ChartSeriesPanel()
+{
+ doUpdateModel(nullptr);
+
+ mxCBLabel.reset();
+ mxCBTrendline.reset();
+ mxCBXError.reset();
+ mxCBYError.reset();
+
+ mxRBPrimaryAxis.reset();
+ mxRBSecondaryAxis.reset();
+
+ mxBoxLabelPlacement.reset();
+ mxLBLabelPlacement.reset();
+
+ mxFTSeriesName.reset();
+ mxFTSeriesTemplate.reset();
+}
+
+void ChartSeriesPanel::Initialize()
+{
+ mxModel->addModifyListener(mxListener);
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+
+ updateData();
+
+ Link<weld::Toggleable&,void> aLink = LINK(this, ChartSeriesPanel, CheckBoxHdl);
+ mxCBLabel->connect_toggled(aLink);
+ mxCBTrendline->connect_toggled(aLink);
+ mxCBXError->connect_toggled(aLink);
+ mxCBYError->connect_toggled(aLink);
+
+ Link<weld::Toggleable&,void> aLink2 = LINK(this, ChartSeriesPanel, RadioBtnHdl);
+ mxRBPrimaryAxis->connect_toggled(aLink2);
+ mxRBSecondaryAxis->connect_toggled(aLink2);
+
+ mxLBLabelPlacement->connect_changed(LINK(this, ChartSeriesPanel, ListBoxHdl));
+}
+
+void ChartSeriesPanel::updateData()
+{
+ if (!mbModelValid)
+ return;
+
+ OUString aCID = getCID(mxModel);
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ if (eType!=OBJECTTYPE_DATA_SERIES &&
+ eType != OBJECTTYPE_DATA_POINT &&
+ eType != OBJECTTYPE_DATA_CURVE)
+ return;
+
+ SolarMutexGuard aGuard;
+ bool bLabelVisible = isDataLabelVisible(mxModel, aCID);
+ mxCBLabel->set_active(bLabelVisible);
+ mxCBTrendline->set_active(isTrendlineVisible(mxModel, aCID));
+ mxCBXError->set_active(isErrorBarVisible(mxModel, aCID, false));
+ mxCBYError->set_active(isErrorBarVisible(mxModel, aCID, true));
+
+ bool bPrimaryAxis = isPrimaryAxis(mxModel, aCID);
+ mxRBPrimaryAxis->set_active(bPrimaryAxis);
+ mxRBSecondaryAxis->set_active(!bPrimaryAxis);
+
+ mxBoxLabelPlacement->set_sensitive(bLabelVisible);
+ mxLBLabelPlacement->set_active(getDataLabelPlacement(mxModel, aCID));
+
+ OUString aFrameLabel = mxFTSeriesTemplate->get_label();
+ aFrameLabel = aFrameLabel.replaceFirst("%1", getSeriesLabel(mxModel, aCID));
+ mxFTSeriesName->set_label(aFrameLabel);
+}
+
+std::unique_ptr<PanelLayout> ChartSeriesPanel::Create (
+ weld::Widget* pParent,
+ ChartController* pController)
+{
+ if (pParent == nullptr)
+ throw lang::IllegalArgumentException("no parent Window given to ChartSeriesPanel::Create", nullptr, 0);
+
+ return std::make_unique<ChartSeriesPanel>(pParent, pController);
+}
+
+void ChartSeriesPanel::DataChanged(const DataChangedEvent& rEvent)
+{
+ PanelLayout::DataChanged(rEvent);
+ updateData();
+}
+
+void ChartSeriesPanel::HandleContextChange(
+ const vcl::EnumContext& )
+{
+ updateData();
+}
+
+void ChartSeriesPanel::NotifyItemUpdate(
+ sal_uInt16 /*nSID*/,
+ SfxItemState /*eState*/,
+ const SfxPoolItem* /*pState*/ )
+{
+}
+
+void ChartSeriesPanel::modelInvalid()
+{
+ mbModelValid = false;
+}
+
+void ChartSeriesPanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ mxModel->removeModifyListener(mxListener);
+ }
+
+ css::uno::Reference<css::view::XSelectionSupplier> oldSelectionSupplier(
+ mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (oldSelectionSupplier.is()) {
+ oldSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
+ }
+
+ mxModel = xModel;
+ mbModelValid = mxModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ mxModel->addModifyListener(mxListener);
+
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+}
+
+void ChartSeriesPanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+void ChartSeriesPanel::selectionChanged(bool bCorrectType)
+{
+ if (bCorrectType)
+ updateData();
+}
+
+IMPL_LINK(ChartSeriesPanel, CheckBoxHdl, weld::Toggleable&, rCheckBox, void)
+{
+ bool bChecked = rCheckBox.get_active();
+ OUString aCID = getCID(mxModel);
+ if (&rCheckBox == mxCBLabel.get())
+ setDataLabelVisible(mxModel, aCID, bChecked);
+ else if (&rCheckBox == mxCBTrendline.get())
+ setTrendlineVisible(mxModel, aCID, bChecked);
+ else if (&rCheckBox == mxCBXError.get())
+ setErrorBarVisible(mxModel, aCID, false, bChecked);
+ else if (&rCheckBox == mxCBYError.get())
+ setErrorBarVisible(mxModel, aCID, true, bChecked);
+}
+
+IMPL_LINK_NOARG(ChartSeriesPanel, RadioBtnHdl, weld::Toggleable&, void)
+{
+ OUString aCID = getCID(mxModel);
+ bool bChecked = mxRBPrimaryAxis->get_active();
+
+ setAttachedAxisType(mxModel, aCID, bChecked);
+}
+
+IMPL_LINK_NOARG(ChartSeriesPanel, ListBoxHdl, weld::ComboBox&, void)
+{
+ OUString aCID = getCID(mxModel);
+
+ sal_Int32 nPos = mxLBLabelPlacement->get_active();
+ setDataLabelPlacement(mxModel, aCID, nPos);
+}
+
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSeriesPanel.hxx b/chart2/source/controller/sidebar/ChartSeriesPanel.hxx
new file mode 100644
index 000000000..b457667ec
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSeriesPanel.hxx
@@ -0,0 +1,110 @@
+/* -*- 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/sidebar/ControllerItem.hxx>
+#include <sfx2/sidebar/IContextChangeReceiver.hxx>
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <sfx2/sidebar/PanelLayout.hxx>
+
+#include "ChartSidebarModifyListener.hxx"
+#include "ChartSidebarSelectionListener.hxx"
+
+namespace com::sun::star::util { class XModifyListener; }
+namespace com::sun::star::view { class XSelectionChangeListener; }
+
+namespace chart {
+
+class ChartController;
+
+namespace sidebar {
+
+class ChartSeriesPanel : public PanelLayout,
+ public ::sfx2::sidebar::IContextChangeReceiver,
+ public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent,
+ public ChartSidebarSelectionListenerParent
+{
+public:
+ static std::unique_ptr<PanelLayout> Create(
+ weld::Widget* pParent,
+ ChartController* pController);
+
+ virtual void DataChanged(
+ const DataChangedEvent& rEvent) override;
+
+ virtual void HandleContextChange(
+ const vcl::EnumContext& rContext) override;
+
+ virtual void NotifyItemUpdate(
+ const sal_uInt16 nSId,
+ const SfxItemState eState,
+ const SfxPoolItem* pState) override;
+
+ virtual void GetControlState(
+ const sal_uInt16 /*nSId*/,
+ boost::property_tree::ptree& /*rState*/) override {};
+
+ // constructor/destructor
+ ChartSeriesPanel(
+ weld::Widget* pParent,
+ ChartController* pController);
+ virtual ~ChartSeriesPanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void selectionChanged(bool bCorrectType) override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) override;
+
+private:
+ //ui controls
+ std::unique_ptr<weld::CheckButton> mxCBLabel;
+ std::unique_ptr<weld::CheckButton> mxCBTrendline;
+ std::unique_ptr<weld::CheckButton> mxCBXError;
+ std::unique_ptr<weld::CheckButton> mxCBYError;
+
+ std::unique_ptr<weld::RadioButton> mxRBPrimaryAxis;
+ std::unique_ptr<weld::RadioButton> mxRBSecondaryAxis;
+
+ std::unique_ptr<weld::Widget> mxBoxLabelPlacement;
+ std::unique_ptr<weld::ComboBox> mxLBLabelPlacement;
+
+ std::unique_ptr<weld::Label> mxFTSeriesName;
+ std::unique_ptr<weld::Label> mxFTSeriesTemplate;
+
+ rtl::Reference<::chart::ChartModel> mxModel;
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+ css::uno::Reference<css::view::XSelectionChangeListener> mxSelectionListener;
+
+ bool mbModelValid;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ DECL_LINK(CheckBoxHdl, weld::Toggleable&, void);
+ DECL_LINK(RadioBtnHdl, weld::Toggleable&, void);
+ DECL_LINK(ListBoxHdl, weld::ComboBox&, void);
+};
+
+} } // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSidebarModifyListener.cxx b/chart2/source/controller/sidebar/ChartSidebarModifyListener.cxx
new file mode 100644
index 000000000..adee06ddd
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSidebarModifyListener.cxx
@@ -0,0 +1,39 @@
+/* -*- 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 "ChartSidebarModifyListener.hxx"
+
+namespace chart::sidebar
+{
+ChartSidebarModifyListenerParent::~ChartSidebarModifyListenerParent() {}
+
+ChartSidebarModifyListener::ChartSidebarModifyListener(ChartSidebarModifyListenerParent* pParent)
+ : mpParent(pParent)
+{
+}
+
+ChartSidebarModifyListener::~ChartSidebarModifyListener() {}
+
+void ChartSidebarModifyListener::modified(const css::lang::EventObject& /*rEvent*/)
+{
+ if (mpParent)
+ mpParent->updateData();
+}
+
+void ChartSidebarModifyListener::disposing(const css::lang::EventObject& /*rEvent*/)
+{
+ if (!mpParent)
+ return;
+
+ mpParent->modelInvalid();
+ mpParent = nullptr;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSidebarModifyListener.hxx b/chart2/source/controller/sidebar/ChartSidebarModifyListener.hxx
new file mode 100644
index 000000000..afcbbdab5
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSidebarModifyListener.hxx
@@ -0,0 +1,42 @@
+/* -*- 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 <com/sun/star/util/XModifyListener.hpp>
+#include <cppuhelper/implbase.hxx>
+
+namespace chart::sidebar
+{
+class ChartSidebarModifyListenerParent
+{
+public:
+ virtual ~ChartSidebarModifyListenerParent();
+
+ virtual void updateData() = 0;
+
+ virtual void modelInvalid() = 0;
+};
+
+class ChartSidebarModifyListener : public cppu::WeakImplHelper<css::util::XModifyListener>
+{
+public:
+ explicit ChartSidebarModifyListener(ChartSidebarModifyListenerParent* pParent);
+ virtual ~ChartSidebarModifyListener() override;
+
+ virtual void SAL_CALL modified(const css::lang::EventObject& rEvent) override;
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) override;
+
+private:
+ ChartSidebarModifyListenerParent* mpParent;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx
new file mode 100644
index 000000000..c3757a3b8
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx
@@ -0,0 +1,84 @@
+/* -*- 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 "ChartSidebarSelectionListener.hxx"
+
+#include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/frame/XController.hpp>
+
+#include <ObjectIdentifier.hxx>
+
+namespace chart::sidebar {
+
+ChartSidebarSelectionListenerParent::~ChartSidebarSelectionListenerParent()
+{
+}
+
+ChartSidebarSelectionListener::ChartSidebarSelectionListener(
+ ChartSidebarSelectionListenerParent* pParent):
+ mpParent(pParent)
+{
+}
+
+ChartSidebarSelectionListener::ChartSidebarSelectionListener(
+ ChartSidebarSelectionListenerParent* pParent,
+ ObjectType eType):
+ mpParent(pParent)
+{
+ maTypes.push_back(eType);
+}
+
+ChartSidebarSelectionListener::~ChartSidebarSelectionListener()
+{
+}
+
+void ChartSidebarSelectionListener::selectionChanged(const css::lang::EventObject& rEvent)
+{
+ if (!mpParent)
+ return;
+
+ bool bCorrectObjectSelected = false;
+
+ css::uno::Reference<css::frame::XController> xController(rEvent.Source, css::uno::UNO_QUERY);
+ if (xController.is())
+ {
+ css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
+ if (xSelectionSupplier.is())
+ {
+ css::uno::Any aAny = xSelectionSupplier->getSelection();
+ if (aAny.hasValue())
+ {
+ OUString aCID;
+ aAny >>= aCID;
+ ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+ bCorrectObjectSelected = std::any_of(maTypes.begin(), maTypes.end(),
+ [eType](const ObjectType& eTypeInVector) { return eType == eTypeInVector; });
+ }
+ }
+ }
+
+ mpParent->selectionChanged(bCorrectObjectSelected);
+}
+
+void ChartSidebarSelectionListener::disposing(const css::lang::EventObject& /*rEvent*/)
+{
+ if (!mpParent)
+ return;
+
+ mpParent = nullptr;
+}
+
+void ChartSidebarSelectionListener::setAcceptedTypes(std::vector<ObjectType>&& aTypes)
+{
+ maTypes = std::move(aTypes);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx
new file mode 100644
index 000000000..e8cea5003
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx
@@ -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/.
+ */
+
+#pragma once
+
+#include <com/sun/star/view/XSelectionChangeListener.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <ObjectIdentifier.hxx>
+
+#include <vector>
+
+namespace chart::sidebar
+{
+class ChartSidebarSelectionListenerParent
+{
+public:
+ virtual ~ChartSidebarSelectionListenerParent();
+
+ virtual void selectionChanged(bool bSelected) = 0;
+};
+
+class ChartSidebarSelectionListener
+ : public cppu::WeakImplHelper<css::view::XSelectionChangeListener>
+{
+public:
+ // listen to all chart selection changes
+ explicit ChartSidebarSelectionListener(ChartSidebarSelectionListenerParent* pParent);
+ // only listen to the changes of eType
+ ChartSidebarSelectionListener(ChartSidebarSelectionListenerParent* pParent, ObjectType eType);
+ virtual ~ChartSidebarSelectionListener() override;
+
+ virtual void SAL_CALL selectionChanged(const css::lang::EventObject& rEvent) override;
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) override;
+
+ void setAcceptedTypes(std::vector<ObjectType>&& aTypes);
+
+private:
+ ChartSidebarSelectionListenerParent* mpParent;
+
+ std::vector<ObjectType> maTypes;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartTypePanel.cxx b/chart2/source/controller/sidebar/ChartTypePanel.cxx
new file mode 100644
index 000000000..9c5a7ba43
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartTypePanel.cxx
@@ -0,0 +1,437 @@
+/* -*- 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 "ChartTypePanel.hxx"
+#include <TimerTriggeredControllerLock.hxx>
+
+#include <ChartController.hxx>
+#include <ChartModelHelper.hxx>
+#include <ChartModel.hxx>
+#include <ChartResourceGroups.hxx>
+#include <ChartTypeDialogController.hxx>
+#include <ChartTypeManager.hxx>
+#include <ChartTypeTemplate.hxx>
+#include <DiagramHelper.hxx>
+#include <Diagram.hxx>
+#include <unonames.hxx>
+
+#include <svtools/valueset.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace css;
+using namespace css::uno;
+
+namespace chart::sidebar
+{
+ChartTypePanel::ChartTypePanel(weld::Widget* pParent, ::chart::ChartController* pController)
+ : PanelLayout(pParent, "ChartTypePanel", "modules/schart/ui/sidebartype.ui")
+ , mxListener(new ChartSidebarModifyListener(this))
+ , mbModelValid(true)
+ , m_pDim3DLookResourceGroup(new Dim3DLookResourceGroup(m_xBuilder.get()))
+ , m_pStackingResourceGroup(new StackingResourceGroup(m_xBuilder.get()))
+ , m_pSplineResourceGroup(
+ new SplineResourceGroup(m_xBuilder.get(), pController->GetChartFrame()))
+ , m_pGeometryResourceGroup(new GeometryResourceGroup(m_xBuilder.get()))
+ , m_pSortByXValuesResourceGroup(new SortByXValuesResourceGroup(m_xBuilder.get()))
+ , m_xChartModel(pController->getChartModel())
+ , m_aChartTypeDialogControllerList(0)
+ , m_pCurrentMainType(nullptr)
+ , m_nChangingCalls(0)
+ , m_aTimerTriggeredControllerLock(m_xChartModel)
+ , m_xMainTypeList(m_xBuilder->weld_combo_box("cmb_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(120, 40), MapMode(MapUnit::MapAppFont)));
+ m_xSubTypeListWin->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xMainTypeList->connect_changed(LINK(this, ChartTypePanel, SelectMainTypeHdl));
+ m_xSubTypeList->SetSelectHdl(LINK(this, ChartTypePanel, 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_pDim3DLookResourceGroup->setChangeListener(this);
+ m_pStackingResourceGroup->setChangeListener(this);
+ m_pSplineResourceGroup->setChangeListener(this);
+ m_pGeometryResourceGroup->setChangeListener(this);
+ m_pSortByXValuesResourceGroup->setChangeListener(this);
+
+ Initialize();
+}
+
+ChartTypePanel::~ChartTypePanel()
+{
+ doUpdateModel(nullptr);
+
+ //delete all dialog controller
+ m_aChartTypeDialogControllerList.clear();
+
+ //delete all resource helpers
+ m_pDim3DLookResourceGroup.reset();
+ m_pStackingResourceGroup.reset();
+ m_pSplineResourceGroup.reset();
+ m_pGeometryResourceGroup.reset();
+ m_pSortByXValuesResourceGroup.reset();
+ m_xSubTypeListWin.reset();
+ m_xSubTypeList.reset();
+
+ m_xSubTypeListWin.reset();
+ m_xSubTypeList.reset();
+ m_xMainTypeList.reset();
+}
+
+IMPL_LINK_NOARG(ChartTypePanel, SelectMainTypeHdl, weld::ComboBox&, void) { selectMainType(); }
+
+IMPL_LINK_NOARG(ChartTypePanel, SelectSubTypeHdl, ValueSet*, void)
+{
+ if (m_pCurrentMainType)
+ {
+ ChartTypeParameter aParameter(getCurrentParameter());
+ m_pCurrentMainType->adjustParameterToSubType(aParameter);
+ fillAllControls(aParameter, false);
+ commitToModel(aParameter);
+ }
+}
+
+void ChartTypePanel::Initialize()
+{
+ if (!m_xChartModel.is())
+ return;
+ rtl::Reference<::chart::ChartTypeManager> xChartTypeManager = m_xChartModel->getTypeManager();
+ rtl::Reference<Diagram> xDiagram = ChartModelHelper::findDiagram(m_xChartModel);
+ DiagramHelper::tTemplateWithServiceName aTemplate
+ = DiagramHelper::getTemplateForDiagram(xDiagram, 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->set_active(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 = ThreeDHelper::detectScheme(xDiagram);
+ 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_xSubTypeList->Hide();
+ m_pDim3DLookResourceGroup->showControls(false);
+ m_pStackingResourceGroup->showControls(false);
+ m_pSplineResourceGroup->showControls(false);
+ m_pGeometryResourceGroup->showControls(false);
+ m_pSortByXValuesResourceGroup->showControls(false);
+ }
+}
+
+void ChartTypePanel::updateData()
+{
+ // Chart Type related
+ if (!m_xChartModel.is())
+ return;
+ rtl::Reference<::chart::ChartTypeManager> xChartTypeManager = m_xChartModel->getTypeManager();
+ rtl::Reference<Diagram> xDiagram = ChartModelHelper::findDiagram(m_xChartModel);
+ DiagramHelper::tTemplateWithServiceName aTemplate
+ = DiagramHelper::getTemplateForDiagram(xDiagram, xChartTypeManager);
+ OUString aServiceName(aTemplate.sServiceName);
+
+ //sal_uInt16 nM = 0;
+ for (auto const& elem : m_aChartTypeDialogControllerList)
+ {
+ if (elem->isSubType(aServiceName))
+ {
+ //m_pMainTypeList->SelectEntryPos(nM);
+ //m_pMainTypeList->select_entry_region(nM, nM);
+ break;
+ }
+ //++nM;
+ }
+}
+
+void ChartTypePanel::DataChanged(const DataChangedEvent& rEvent)
+{
+ PanelLayout::DataChanged(rEvent);
+ updateData();
+}
+
+void ChartTypePanel::HandleContextChange(const vcl::EnumContext& rContext)
+{
+ if (maContext == rContext)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ maContext = rContext;
+ updateData();
+}
+
+void ChartTypePanel::modelInvalid() { mbModelValid = false; }
+
+void ChartTypePanel::doUpdateModel(rtl::Reference<::chart::ChartModel> xModel)
+{
+ if (mbModelValid)
+ {
+ m_xChartModel->removeModifyListener(mxListener);
+ }
+
+ m_xChartModel = xModel;
+ mbModelValid = m_xChartModel.is();
+
+ if (!mbModelValid)
+ return;
+
+ m_xChartModel->addModifyListener(mxListener);
+}
+
+void ChartTypePanel::updateModel(css::uno::Reference<css::frame::XModel> xModel)
+{
+ ::chart::ChartModel* pModel = dynamic_cast<::chart::ChartModel*>(xModel.get());
+ assert(!xModel || pModel);
+ doUpdateModel(pModel);
+}
+
+rtl::Reference<::chart::ChartTypeTemplate> ChartTypePanel::getCurrentTemplate() const
+{
+ if (m_pCurrentMainType && m_xChartModel.is())
+ {
+ ChartTypeParameter aParameter(getCurrentParameter());
+ m_pCurrentMainType->adjustParameterToSubType(aParameter);
+ rtl::Reference<::chart::ChartTypeManager> xChartTypeManager
+ = m_xChartModel->getTypeManager();
+ return m_pCurrentMainType->getCurrentTemplate(aParameter, xChartTypeManager);
+ }
+ return nullptr;
+}
+
+ChartTypeDialogController* ChartTypePanel::getSelectedMainType()
+{
+ ChartTypeDialogController* pTypeController = nullptr;
+ auto nM = static_cast<std::vector<ChartTypeDialogController*>::size_type>(
+ m_xMainTypeList->get_active());
+ if (nM < m_aChartTypeDialogControllerList.size())
+ pTypeController = m_aChartTypeDialogControllerList[nM].get();
+ return pTypeController;
+}
+
+void ChartTypePanel::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 ChartTypePanel::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--;
+}
+
+ChartTypeParameter ChartTypePanel::getCurrentParameter() 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 ChartTypePanel::stateChanged()
+{
+ if (m_nChangingCalls)
+ return;
+ m_nChangingCalls++;
+
+ ChartTypeParameter aParameter(getCurrentParameter());
+ if (m_pCurrentMainType)
+ {
+ m_pCurrentMainType->adjustParameterToSubType(aParameter);
+ m_pCurrentMainType->adjustSubTypeAndEnableControls(aParameter);
+ }
+ commitToModel(aParameter);
+
+ //detect the new ThreeDLookScheme
+ rtl::Reference<Diagram> xDiagram = ChartModelHelper::findDiagram(m_xChartModel);
+ aParameter.eThreeDLookScheme = ThreeDHelper::detectScheme(xDiagram);
+ 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--;
+}
+
+void ChartTypePanel::commitToModel(const ChartTypeParameter& rParameter)
+{
+ if (!m_pCurrentMainType)
+ return;
+
+ m_aTimerTriggeredControllerLock.startTimer();
+ m_pCurrentMainType->commitToModel(rParameter, m_xChartModel);
+}
+
+void ChartTypePanel::selectMainType()
+{
+ ChartTypeParameter aParameter(getCurrentParameter());
+
+ 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
+ = ThreeDHelper::detectScheme(ChartModelHelper::findDiagram(m_xChartModel));
+ if (!aParameter.b3DLook
+ && aParameter.eThreeDLookScheme != ThreeDLookScheme::ThreeDLookScheme_Realistic)
+ aParameter.eThreeDLookScheme = ThreeDLookScheme::ThreeDLookScheme_Realistic;
+
+ rtl::Reference<Diagram> xDiagram = ChartModelHelper::findDiagram(m_xChartModel);
+ try
+ {
+ 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);
+}
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartTypePanel.hxx b/chart2/source/controller/sidebar/ChartTypePanel.hxx
new file mode 100644
index 000000000..5555eba2f
--- /dev/null
+++ b/chart2/source/controller/sidebar/ChartTypePanel.hxx
@@ -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 .
+ */
+#pragma once
+
+#include <sfx2/sidebar/IContextChangeReceiver.hxx>
+#include <sfx2/sidebar/SidebarModelUpdate.hxx>
+#include <sfx2/sidebar/PanelLayout.hxx>
+#include <vcl/EnumContext.hxx>
+#include "ChartSidebarModifyListener.hxx"
+#include <ChartTypeDialogController.hxx>
+#include <ChartTypeTemplateProvider.hxx>
+#include <TimerTriggeredControllerLock.hxx>
+
+namespace com::sun::star::util
+{
+class XModifyListener;
+}
+
+namespace weld
+{
+class CustomWeld;
+}
+
+namespace chart
+{
+class ChartController;
+class Dim3DLookResourceGroup;
+class StackingResourceGroup;
+class SplineResourceGroup;
+class GeometryResourceGroup;
+class ChartTypeParameter;
+class SortByXValuesResourceGroup;
+
+namespace sidebar
+{
+class ChartTypePanel : public ResourceChangeListener,
+ public PanelLayout,
+ public ::sfx2::sidebar::IContextChangeReceiver,
+ public sfx2::sidebar::SidebarModelUpdate,
+ public ChartSidebarModifyListenerParent,
+ public ChartTypeTemplateProvider
+{
+public:
+ virtual void DataChanged(const DataChangedEvent& rEvent) override;
+
+ virtual void HandleContextChange(const vcl::EnumContext& rContext) override;
+
+ // constructor/destructor
+ ChartTypePanel(weld::Widget* pParent, ::chart::ChartController* pController);
+
+ virtual ~ChartTypePanel() override;
+
+ virtual void updateData() override;
+ virtual void modelInvalid() override;
+
+ virtual void updateModel(css::uno::Reference<css::frame::XModel> xModel) 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 getCurrentParameter() const;
+
+ virtual void stateChanged() override;
+
+ void commitToModel(const ChartTypeParameter& rParameter);
+ void selectMainType();
+
+ DECL_LINK(SelectMainTypeHdl, weld::ComboBox&, void);
+ DECL_LINK(SelectSubTypeHdl, ValueSet*, void);
+
+ vcl::EnumContext maContext;
+
+ css::uno::Reference<css::util::XModifyListener> mxListener;
+
+ bool mbModelValid;
+
+ void Initialize();
+ void doUpdateModel(rtl::Reference<::chart::ChartModel> xModel);
+
+ 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::ComboBox> m_xMainTypeList;
+ std::unique_ptr<ValueSet> m_xSubTypeList;
+ std::unique_ptr<weld::CustomWeld> m_xSubTypeListWin;
+};
+}
+} // end of namespace ::chart::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */