chart2/inc/ChartView.hxx                               |    5 
 chart2/source/view/axes/VAxisBase.cxx                  |    3 
 chart2/source/view/axes/VAxisBase.hxx                  |    5 
 chart2/source/view/axes/VCartesianAxis.cxx             |    5 
 chart2/source/view/axes/VCartesianAxis.hxx             |    4 
 chart2/source/view/axes/VCartesianCoordinateSystem.cxx |    5 
 chart2/source/view/axes/VCartesianCoordinateSystem.hxx |    3 
 chart2/source/view/axes/VCoordinateSystem.cxx          |    3 
 chart2/source/view/axes/VPolarCoordinateSystem.cxx     |    3 
 chart2/source/view/axes/VPolarCoordinateSystem.hxx     |    3 
 chart2/source/view/charttypes/VSeriesPlotter.cxx       |  142 +++++++++++++++++
 chart2/source/view/inc/DataTableView.hxx               |   17 +-
 chart2/source/view/inc/LegendEntryProvider.hxx         |    9 +
 chart2/source/view/inc/VCoordinateSystem.hxx           |    4 
 chart2/source/view/inc/VSeriesPlotter.hxx              |   15 +
 chart2/source/view/main/ChartView.cxx                  |   13 -
 chart2/source/view/main/DataTableView.cxx              |  127 +++++++++++----
 include/svx/svdotable.hxx                              |    2 
 svx/source/table/svdotable.cxx                         |   12 +
 19 files changed, 328 insertions(+), 52 deletions(-)

New commits:
commit 45556e32ef38188e555a3dc565b4fb2ca74aa05c
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Mon Jul 18 08:12:19 2022 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Wed Aug 24 20:14:29 2022 +0200

    chart2: Data table rendering of keys (legend symbols)
    
    Change-Id: Iff13b188df18fe8f9919274869774f53f2ea323b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138299
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit 9d6ffcc0572cc7917651489c69ca4b3452e89a89)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138585
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/chart2/inc/ChartView.hxx b/chart2/inc/ChartView.hxx
index 2830e89309f8..e489a2d7d68e 100644
--- a/chart2/inc/ChartView.hxx
+++ b/chart2/inc/ChartView.hxx
@@ -181,6 +181,8 @@ public:
 
     void setViewDirty();
 
+    css::uno::Reference<css::uno::XComponentContext> const& 
getComponentContext() { return m_xCC;}
+
     /// See sfx2::XmlDump::dumpAsXml().
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
 
@@ -206,8 +208,7 @@ private: //methods
 private: //member
     ::osl::Mutex m_aMutex;
 
-    css::uno::Reference< css::uno::XComponentContext>
-            m_xCC;
+    css::uno::Reference< css::uno::XComponentContext> m_xCC;
 
     chart::ChartModel& mrChartModel;
 
diff --git a/chart2/source/view/axes/VAxisBase.cxx 
b/chart2/source/view/axes/VAxisBase.cxx
index 209fc508f624..86f530a34a1f 100644
--- a/chart2/source/view/axes/VAxisBase.cxx
+++ b/chart2/source/view/axes/VAxisBase.cxx
@@ -247,7 +247,8 @@ void VAxisBase::updateUnscaledValuesAtTicks( TickIter& 
rIter )
 
 void 
VAxisBase::createDataTableView(std::vector<std::unique_ptr<VSeriesPlotter>>& 
/*rSeriesPlotterList*/,
                                     
uno::Reference<util::XNumberFormatsSupplier> const& /*xNumberFormatsSupplier*/,
-                                    uno::Reference<chart2::XChartDocument> 
const& /*xChartDoc*/)
+                                    uno::Reference<chart2::XChartDocument> 
const& /*xChartDoc*/,
+                                    uno::Reference<uno::XComponentContext> 
const& /*rComponentContext*/)
 {
 }
 
diff --git a/chart2/source/view/axes/VAxisBase.hxx 
b/chart2/source/view/axes/VAxisBase.hxx
index 6992ff05fd89..e64df679d458 100644
--- a/chart2/source/view/axes/VAxisBase.hxx
+++ b/chart2/source/view/axes/VAxisBase.hxx
@@ -24,6 +24,7 @@
 #include "Tickmarks.hxx"
 
 namespace com::sun::star::util { class XNumberFormatsSupplier; }
+namespace com::sun::star::uno { class XComponentContext; }
 
 namespace chart
 {
@@ -31,6 +32,7 @@ namespace chart
 class VSeriesPlotter;
 class DataTableView;
 class ChartModel;
+class LegendEntryProvider;
 
 class VAxisBase : public VAxisOrGridBase
 {
@@ -66,7 +68,8 @@ public:
 
     virtual void 
createDataTableView(std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList,
                                      
css::uno::Reference<css::util::XNumberFormatsSupplier> const& 
xNumberFormatsSupplier,
-                                     
css::uno::Reference<css::chart2::XChartDocument> const& xChartDoc);
+                                     
css::uno::Reference<css::chart2::XChartDocument> const& xChartDoc,
+                                     
css::uno::Reference<css::uno::XComponentContext> const& rComponentContext);
 
     std::shared_ptr<DataTableView> getDataTableView() { return 
m_pDataTableView; }
 
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx 
b/chart2/source/view/axes/VCartesianAxis.cxx
index 0a731bf086d2..76884e8fc255 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -2009,11 +2009,12 @@ void VCartesianAxis::createShapes()
 
 void 
VCartesianAxis::createDataTableView(std::vector<std::unique_ptr<VSeriesPlotter>>&
 rSeriesPlotterList,
                                          
uno::Reference<util::XNumberFormatsSupplier> const& xNumberFormatsSupplier,
-                                         
uno::Reference<chart2::XChartDocument> const& xChartDoc)
+                                         
uno::Reference<chart2::XChartDocument> const& xChartDoc,
+                                         
uno::Reference<uno::XComponentContext> const& rComponentContext)
 {
     if (m_aAxisProperties.m_bDisplayDataTable)
     {
-        m_pDataTableView.reset(new DataTableView(xChartDoc, 
m_aAxisProperties.m_xDataTableModel));
+        m_pDataTableView.reset(new DataTableView(xChartDoc, 
m_aAxisProperties.m_xDataTableModel, rComponentContext));
         m_pDataTableView->initializeValues(rSeriesPlotterList);
         m_xNumberFormatsSupplier = xNumberFormatsSupplier;
     }
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx 
b/chart2/source/view/axes/VCartesianAxis.hxx
index 1027e4fc2188..2be55c239c67 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -23,7 +23,6 @@
 
 namespace chart
 {
-
 class VCartesianAxis : public VAxisBase
 {
     // public methods
@@ -101,7 +100,8 @@ public:
 
     void createDataTableView(std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList,
                              
css::uno::Reference<css::util::XNumberFormatsSupplier> const& 
xNumberFormatsSupplier,
-                             css::uno::Reference<css::chart2::XChartDocument> 
const& xChartDoc) override;
+                             css::uno::Reference<css::chart2::XChartDocument> 
const& xChartDoc,
+                             css::uno::Reference<css::uno::XComponentContext> 
const& rComponentContext) override;
 private: //methods
     /**
      * Go through all tick label positions and decide which labels to display
diff --git a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx 
b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
index 53eac1515e0c..519f7e866679 100644
--- a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
@@ -103,7 +103,8 @@ void VCartesianCoordinateSystem::createVAxisList(
             , const awt::Size& rFontReferenceSize
             , const awt::Rectangle& rMaximumSpaceForLabels
             , bool bLimitSpaceForLabels
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList)
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList
+            , uno::Reference<uno::XComponentContext> const& rComponentContext)
 {
     // note: using xChartDoc itself as XNumberFormatsSupplier would cause
     // a leak from VCartesianAxis due to cyclic reference
@@ -167,7 +168,7 @@ void VCartesianCoordinateSystem::createVAxisList(
             apVAxis->set3DWallPositions( m_eLeftWallPos, m_eBackWallPos, 
m_eBottomPos );
 
             
apVAxis->initAxisLabelProperties(rFontReferenceSize,rMaximumSpaceForLabels);
-            apVAxis->createDataTableView(rSeriesPlotterList, 
xNumberFormatsSupplier, xChartDoc);
+            apVAxis->createDataTableView(rSeriesPlotterList, 
xNumberFormatsSupplier, xChartDoc, rComponentContext);
         }
     }
 }
diff --git a/chart2/source/view/axes/VCartesianCoordinateSystem.hxx 
b/chart2/source/view/axes/VCartesianCoordinateSystem.hxx
index a1d8ce070046..67b735ef2f2f 100644
--- a/chart2/source/view/axes/VCartesianCoordinateSystem.hxx
+++ b/chart2/source/view/axes/VCartesianCoordinateSystem.hxx
@@ -35,7 +35,8 @@ public:
             , const css::awt::Size& rFontReferenceSize
             , const css::awt::Rectangle& rMaximumSpaceForLabels
             , bool bLimitSpaceForLabels
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList) override;
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList
+            , css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext) override;
 
     virtual void initVAxisInList() override;
     virtual void updateScalesAndIncrementsOnAxes() override;
diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx 
b/chart2/source/view/axes/VCoordinateSystem.cxx
index bd5e8683e679..68f83a3f74aa 100644
--- a/chart2/source/view/axes/VCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VCoordinateSystem.cxx
@@ -330,7 +330,8 @@ void VCoordinateSystem::createVAxisList(
             , const awt::Size& /* rFontReferenceSize */
             , const awt::Rectangle& /* rMaximumSpaceForLabels */
             , bool /* bLimitSpaceForLabels */
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
/*rSeriesPlotterList*/)
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
/*rSeriesPlotterList*/
+            , uno::Reference<uno::XComponentContext> const& 
/*rComponentContext*/)
 {
 }
 
diff --git a/chart2/source/view/axes/VPolarCoordinateSystem.cxx 
b/chart2/source/view/axes/VPolarCoordinateSystem.cxx
index be8f4baac53c..358670ca7c69 100644
--- a/chart2/source/view/axes/VPolarCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VPolarCoordinateSystem.cxx
@@ -72,7 +72,8 @@ void VPolarCoordinateSystem::createVAxisList(
             , const awt::Size& rFontReferenceSize
             , const awt::Rectangle& rMaximumSpaceForLabels
             , bool //bLimitSpaceForLabels
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
/*rSeriesPlotterList*/)
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
/*rSeriesPlotterList*/
+            , uno::Reference<uno::XComponentContext> const& 
/*rComponentContext*/)
 {
     // note: using xChartDoc itself as XNumberFormatsSupplier would cause
     // a leak from VPolarAxis due to cyclic reference
diff --git a/chart2/source/view/axes/VPolarCoordinateSystem.hxx 
b/chart2/source/view/axes/VPolarCoordinateSystem.hxx
index 63d1741b4602..7d83a84f125e 100644
--- a/chart2/source/view/axes/VPolarCoordinateSystem.hxx
+++ b/chart2/source/view/axes/VPolarCoordinateSystem.hxx
@@ -39,7 +39,8 @@ public:
             , const css::awt::Size& rFontReferenceSize
             , const css::awt::Rectangle& rMaximumSpaceForLabels
             , bool bLimitSpaceForLabels
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList) override;
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList
+            , css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext) override;
 
     virtual void initVAxisInList() override;
     virtual void updateScalesAndIncrementsOnAxes() override;
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx 
b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 615695415cb7..0cd15188e84f 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -2517,6 +2517,53 @@ std::vector< ViewLegendEntry > 
VSeriesPlotter::createLegendEntries(
     return aResult;
 }
 
+std::vector<ViewLegendSymbol> VSeriesPlotter::createSymbols(const awt::Size& 
rEntryKeyAspectRatio
+            , const css::uno::Reference<css::drawing::XShapes>& xTarget
+            , const Reference< lang::XMultiServiceFactory >& xShapeFactory
+            , const Reference<uno::XComponentContext>& xContext)
+{
+    std::vector<ViewLegendSymbol> aResult;
+
+    if( xTarget.is() )
+    {
+        bool bBreak = false;
+        bool bFirstSeries = true;
+
+        for (std::vector<VDataSeriesGroup> const & rGroupVector : m_aZSlots)
+        {
+            for (VDataSeriesGroup const & rGroup : rGroupVector)
+            {
+                for (std::unique_ptr<VDataSeries> const & pSeries : 
rGroup.m_aSeriesVector)
+                {
+                    if (!pSeries)
+                        continue;
+
+                    if 
(!pSeries->getPropertiesOfSeries()->getPropertyValue("ShowLegendEntry").get<sal_Bool>())
+                    {
+                        continue;
+                    }
+
+                    std::vector<ViewLegendSymbol> aSeriesSymbols = 
createSymbolsForSeries(rEntryKeyAspectRatio, *pSeries, xTarget, xShapeFactory, 
xContext);
+
+                    //add series entries to the result now
+
+                    // use only the first series if VaryColorsByPoint is set 
for the first series
+                    if (bFirstSeries && pSeries->isVaryColorsByPoint())
+                        bBreak = true;
+
+                    bFirstSeries = false;
+
+                    aResult.insert(aResult.end(), aSeriesSymbols.begin(), 
aSeriesSymbols.end());
+                }
+                if (bBreak)
+                    return aResult;
+            }
+        }
+    }
+
+    return aResult;
+}
+
 namespace
 {
 bool lcl_HasVisibleLine( const uno::Reference< beans::XPropertySet >& xProps, 
bool& rbHasDashedLine )
@@ -2862,6 +2909,101 @@ std::vector< ViewLegendEntry > 
VSeriesPlotter::createLegendEntriesForSeries(
     return aResult;
 }
 
+std::vector<ViewLegendSymbol> VSeriesPlotter::createSymbolsForSeries(
+              const awt::Size& rEntryKeyAspectRatio
+            , const VDataSeries& rSeries
+            , const css::uno::Reference<css::drawing::XShapes>& xTarget
+            , const Reference< lang::XMultiServiceFactory >& xShapeFactory
+            , const Reference<uno::XComponentContext>& xContext)
+{
+    std::vector<ViewLegendSymbol> aResult;
+
+    if (!(xTarget.is() && xContext.is()))
+        return aResult;
+
+    try
+    {
+        ViewLegendSymbol aEntry;
+        bool bVaryColorsByPoint = rSeries.isVaryColorsByPoint();
+        bool bIsPie = 
m_xChartTypeModel->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE);
+        try
+        {
+            if (bIsPie)
+            {
+                bool bDonut = false;
+                if ((m_xChartTypeModelProps->getPropertyValue("UseRings") >>= 
bDonut) && bDonut)
+                    bIsPie = false;
+            }
+        }
+        catch (const uno::Exception&)
+        {
+        }
+
+        if (bVaryColorsByPoint || bIsPie)
+        {
+            Sequence< OUString > aCategoryNames;
+            if (m_pExplicitCategoriesProvider)
+                aCategoryNames = 
m_pExplicitCategoriesProvider->getSimpleCategories();
+            Sequence<sal_Int32> deletedLegendEntries;
+            try
+            {
+                
rSeries.getPropertiesOfSeries()->getPropertyValue("DeletedLegendEntries") >>= 
deletedLegendEntries;
+            }
+            catch (const uno::Exception&)
+            {
+            }
+
+            for (sal_Int32 nIdx=0; nIdx < aCategoryNames.getLength(); ++nIdx)
+            {
+                bool deletedLegendEntry = false;
+                for (const auto& deletedLegendEntryIdx : 
std::as_const(deletedLegendEntries))
+                {
+                    if (nIdx == deletedLegendEntryIdx)
+                    {
+                        deletedLegendEntry = true;
+                        break;
+                    }
+                }
+                if (deletedLegendEntry)
+                    continue;
+
+                // symbol
+                uno::Reference< drawing::XShapes > xSymbolGroup( 
ShapeFactory::getOrCreateShapeFactory(xShapeFactory)->createGroup2D( xTarget ));
+
+                // create the symbol
+                Reference< drawing::XShape > xShape( 
createLegendSymbolForSeries(
+                    rEntryKeyAspectRatio, rSeries, xSymbolGroup, xShapeFactory 
) );
+
+                // set CID to symbol for selection
+                if( xShape.is())
+                {
+                    aEntry.aSymbol.set(xSymbolGroup, uno::UNO_QUERY);
+                }
+            }
+        }
+        else
+        {
+            // symbol
+            uno::Reference< drawing::XShapes > xSymbolGroup( 
ShapeFactory::getOrCreateShapeFactory(xShapeFactory)->createGroup2D(xTarget));
+
+            // create the symbol
+            Reference< drawing::XShape > xShape( createLegendSymbolForSeries(
+                rEntryKeyAspectRatio, rSeries, xSymbolGroup, xShapeFactory ) );
+
+            // set CID to symbol for selection
+            if( xShape.is())
+            {
+                aEntry.aSymbol.set( xSymbolGroup, uno::UNO_QUERY );
+            }
+        }
+    }
+    catch (const uno::Exception &)
+    {
+        DBG_UNHANDLED_EXCEPTION("chart2" );
+    }
+    return aResult;
+}
+
 VSeriesPlotter* VSeriesPlotter::createSeriesPlotter(
     const uno::Reference<XChartType>& xChartTypeModel
     , sal_Int32 nDimensionCount
diff --git a/chart2/source/view/inc/DataTableView.hxx 
b/chart2/source/view/inc/DataTableView.hxx
index e7130d54bc68..edeb7e6a8310 100644
--- a/chart2/source/view/inc/DataTableView.hxx
+++ b/chart2/source/view/inc/DataTableView.hxx
@@ -13,6 +13,10 @@
 #include <com/sun/star/drawing/XShapes.hpp>
 #include <com/sun/star/awt/Rectangle.hpp>
 #include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <DataTable.hxx>
 #include "VLineProperties.hxx"
 
@@ -27,18 +31,25 @@ private:
     css::uno::Reference<css::drawing::XShapes> m_xTarget;
     rtl::Reference<SvxTableShape> m_xTableShape;
     rtl::Reference<DataTable> m_xDataTableModel;
+    css::uno::Reference<css::lang::XMultiServiceFactory> m_xShapeFactory;
+    css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
     VLineProperties m_aLineProperties;
+    std::vector<VSeriesPlotter*> m_pSeriesPlotterList;
 
     std::vector<OUString> m_aDataSeriesNames;
     std::vector<OUString> m_aXValues;
     std::vector<std::vector<OUString>> m_pDataSeriesValues;
 
-    void setCellDefaults(css::uno::Reference<css::beans::XPropertySet>& 
xPropertySet, bool bLeft,
-                         bool bTop, bool bRight, bool bBottom);
+    void
+    
setCellCharAndParagraphProperties(css::uno::Reference<css::beans::XPropertySet>&
 xPropertySet);
+
+    void setCellProperties(css::uno::Reference<css::beans::XPropertySet>& 
xPropertySet, bool bLeft,
+                           bool bTop, bool bRight, bool bBottom);
 
 public:
     DataTableView(css::uno::Reference<css::chart2::XChartDocument> const& 
xChartDoc,
-                  rtl::Reference<DataTable> const& rDataTableModel);
+                  rtl::Reference<DataTable> const& rDataTableModel,
+                  css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext);
     void initializeShapes(const css::uno::Reference<css::drawing::XShapes>& 
xTarget);
     void initializeValues(std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList);
     void createShapes(basegfx::B2DVector const& rStart, basegfx::B2DVector 
const& rEnd,
diff --git a/chart2/source/view/inc/LegendEntryProvider.hxx 
b/chart2/source/view/inc/LegendEntryProvider.hxx
index 1eea73aeeb86..19bfc6680efb 100644
--- a/chart2/source/view/inc/LegendEntryProvider.hxx
+++ b/chart2/source/view/inc/LegendEntryProvider.hxx
@@ -64,6 +64,15 @@ struct ViewLegendEntry
         css::uno::Reference< css::chart2::XFormattedString2 > >  aLabel;
 };
 
+
+struct ViewLegendSymbol
+{
+    /** The legend symbol that represents a data series or other
+        information contained in the legend
+     */
+    css::uno::Reference<css::drawing::XShape> aSymbol;
+};
+
 class LegendEntryProvider
 {
 public:
diff --git a/chart2/source/view/inc/VCoordinateSystem.hxx 
b/chart2/source/view/inc/VCoordinateSystem.hxx
index fdcded9b5235..7c01ad08a47b 100644
--- a/chart2/source/view/inc/VCoordinateSystem.hxx
+++ b/chart2/source/view/inc/VCoordinateSystem.hxx
@@ -39,6 +39,7 @@ namespace com::sun::star::chart2 { class XChartDocument; }
 namespace com::sun::star::chart2 { class XCoordinateSystem; }
 namespace com::sun::star::drawing { class XShapes; }
 namespace com::sun::star::lang { class XMultiServiceFactory; }
+namespace com::sun::star::uno { class XComponentContext; }
 
 namespace chart
 {
@@ -117,7 +118,8 @@ public:
             , const css::awt::Size& rFontReferenceSize
             , const css::awt::Rectangle& rMaximumSpaceForLabels
             , bool bLimitSpaceForLabels
-            , std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList);
+            , std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList
+            , css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext);
 
     virtual void initVAxisInList();
     virtual void updateScalesAndIncrementsOnAxes();
diff --git a/chart2/source/view/inc/VSeriesPlotter.hxx 
b/chart2/source/view/inc/VSeriesPlotter.hxx
index 31b81cf23e51..a3ea7293e2d4 100644
--- a/chart2/source/view/inc/VSeriesPlotter.hxx
+++ b/chart2/source/view/inc/VSeriesPlotter.hxx
@@ -217,7 +217,20 @@ public:
             const css::uno::Reference< css::uno::XComponentContext >& xContext
                 );
 
-    std::vector< VDataSeries* > getAllSeries();
+    std::vector<ViewLegendSymbol> createSymbols(
+              const css::awt::Size& rEntryKeyAspectRatio
+            , const css::uno::Reference<css::drawing::XShapes>& xTarget
+            , const css::uno::Reference<css::lang::XMultiServiceFactory>& 
xShapeFactory
+            , const css::uno::Reference<css::uno::XComponentContext>& 
xContext);
+
+    std::vector<ViewLegendSymbol> createSymbolsForSeries(
+              const css::awt::Size& rEntryKeyAspectRatio
+            , const VDataSeries& rSeries
+            , const css::uno::Reference<css::drawing::XShapes>& xTarget
+            , const css::uno::Reference<css::lang::XMultiServiceFactory>& 
xShapeFactory
+            , const css::uno::Reference<css::uno::XComponentContext>& 
xContext);
+
+    std::vector<VDataSeries*> getAllSeries();
     std::vector<VDataSeries const*> getAllSeries() const;
 
     // This method creates a series plotter of the requested type; e.g. : 
return new PieChart...
diff --git a/chart2/source/view/main/ChartView.cxx 
b/chart2/source/view/main/ChartView.cxx
index ca9555cc1626..d3f5ab65c765 100644
--- a/chart2/source/view/main/ChartView.cxx
+++ b/chart2/source/view/main/ChartView.cxx
@@ -538,8 +538,8 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( 
const CreateShapeParam2D
             CuboidPlanePosition eBottomPos( 
ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( 
xSceneProperties ) );
             pVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, 
eBottomPos );
         }
-
-        pVCooSys->createVAxisList(xChartDoc, rPageSize, 
rParam.maRemainingSpace, rParam.mbUseFixedInnerSize, rSeriesPlotterList);
+        pVCooSys->createVAxisList(xChartDoc, rPageSize, 
rParam.maRemainingSpace, rParam.mbUseFixedInnerSize, rSeriesPlotterList,
+                                  getComponentContext());
     }
 
     // - prepare list of all axis and how they are used
@@ -1393,9 +1393,12 @@ void ChartView::createShapes()
     if(!mxRootShape.is())
         mxRootShape = pShapeFactory->getOrCreateChartRootShape( m_xDrawPage );
 
-    SdrPage* pPage = ChartView::getSdrPage();
-    if(pPage) //it is necessary to use the implementation here as the uno page 
does not provide a propertyset
+    SdrPage* pPage = getSdrPage();
+
+    if (pPage) //it is necessary to use the implementation here as the uno 
page does not provide a propertyset
+    {
         pPage->SetSize(Size(aPageSize.Width,aPageSize.Height));
+    }
     else
     {
         OSL_FAIL("could not set page size correctly");
@@ -1931,7 +1934,7 @@ void ChartView::createShapes2D( const awt::Size& 
rPageSize )
     }
 
     lcl_createLegend(
-        LegendHelper::getLegend( mrChartModel ), mxRootShape, m_xShapeFactory, 
m_xCC,
+        LegendHelper::getLegend( mrChartModel ), mxRootShape, m_xShapeFactory, 
getComponentContext(),
         aParam.maRemainingSpace, rPageSize, mrChartModel, 
aParam.mpSeriesPlotterContainer->getLegendEntryProviderList(),
         lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) );
 
diff --git a/chart2/source/view/main/DataTableView.cxx 
b/chart2/source/view/main/DataTableView.cxx
index 4b83428abe04..1fe3b191b878 100644
--- a/chart2/source/view/main/DataTableView.cxx
+++ b/chart2/source/view/main/DataTableView.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/drawing/LineStyle.hpp>
 #include <com/sun/star/util/XBroadcaster.hpp>
 #include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
 
 #include <o3tl/unit_conversion.hxx>
 
@@ -35,15 +36,6 @@ using namespace css;
 
 namespace chart
 {
-DataTableView::DataTableView(css::uno::Reference<css::chart2::XChartDocument> 
const& xChartDoc,
-                             rtl::Reference<DataTable> const& rDataTableModel)
-    : m_xChartModel(xChartDoc)
-    , m_xDataTableModel(rDataTableModel)
-{
-    uno::Reference<beans::XPropertySet> xProp(m_xDataTableModel);
-    m_aLineProperties.initFromPropertySet(xProp);
-}
-
 namespace
 {
 void setTopCell(uno::Reference<beans::XPropertySet>& xPropertySet)
@@ -66,10 +58,21 @@ void copyProperty(uno::Reference<beans::XPropertySet>& xOut,
 {
     xOut->setPropertyValue(sPropertyName, 
xIn->getPropertyValue(sPropertyName));
 }
+} // end anonymous namespace
+
+DataTableView::DataTableView(uno::Reference<chart2::XChartDocument> const& 
xChartDoc,
+                             rtl::Reference<DataTable> const& rDataTableModel,
+                             uno::Reference<uno::XComponentContext> const& 
rComponentContext)
+    : m_xChartModel(xChartDoc)
+    , m_xDataTableModel(rDataTableModel)
+    , m_xComponentContext(rComponentContext)
+{
+    uno::Reference<beans::XPropertySet> xProp(m_xDataTableModel);
+    m_aLineProperties.initFromPropertySet(xProp);
 }
 
-void DataTableView::setCellDefaults(uno::Reference<beans::XPropertySet>& 
xPropertySet, bool bLeft,
-                                    bool bTop, bool bRight, bool bBottom)
+void DataTableView::setCellCharAndParagraphProperties(
+    uno::Reference<beans::XPropertySet>& xPropertySet)
 {
     uno::Reference<beans::XPropertySet> 
xDataTableProperties(m_xDataTableModel);
 
@@ -114,20 +117,28 @@ void 
DataTableView::setCellDefaults(uno::Reference<beans::XPropertySet>& xProper
     copyProperty(xPropertySet, xDataTableProperties, "CharWeightComplex");
     copyProperty(xPropertySet, xDataTableProperties, "CharWordMode");
 
+    xPropertySet->setPropertyValue("ParaAdjust", 
uno::makeAny(style::ParagraphAdjust_CENTER));
+}
+
+void 
DataTableView::setCellProperties(css::uno::Reference<beans::XPropertySet>& 
xPropertySet,
+                                      bool bLeft, bool bTop, bool bRight, bool 
bBottom)
+{
+    xPropertySet->setPropertyValue("FillColor", uno::makeAny(Color(0xFFFFFF)));
+
+    uno::Reference<beans::XPropertySet> 
xDataTableProperties(m_xDataTableModel);
     float fFontHeight = 0.0;
     xDataTableProperties->getPropertyValue("CharHeight") >>= fFontHeight;
     fFontHeight = o3tl::convert(fFontHeight, o3tl::Length::pt, 
o3tl::Length::mm100);
-    uno::Any aXDistanceAny(sal_Int32(std::round(fFontHeight * 0.18f)));
-    uno::Any aYDistanceAny(sal_Int32(std::round(fFontHeight * 0.30f)));
-    xPropertySet->setPropertyValue("TextLeftDistance", aXDistanceAny);
-    xPropertySet->setPropertyValue("TextRightDistance", aXDistanceAny);
-    xPropertySet->setPropertyValue("TextUpperDistance", aYDistanceAny);
-    xPropertySet->setPropertyValue("TextLowerDistance", aYDistanceAny);
+    sal_Int32 nXDistance = std::round(fFontHeight * 0.18f);
+    sal_Int32 nYDistance = std::round(fFontHeight * 0.30f);
+
+    xPropertySet->setPropertyValue("TextLeftDistance", 
uno::makeAny(nXDistance));
+    xPropertySet->setPropertyValue("TextRightDistance", 
uno::makeAny(nXDistance));
+    xPropertySet->setPropertyValue("TextUpperDistance", 
uno::makeAny(nYDistance));
+    xPropertySet->setPropertyValue("TextLowerDistance", 
uno::makeAny(nYDistance));
 
-    xPropertySet->setPropertyValue("FillColor", uno::makeAny(Color(0xFFFFFF)));
     xPropertySet->setPropertyValue("TextVerticalAdjust",
                                    
uno::makeAny(drawing::TextVerticalAdjust_TOP));
-    xPropertySet->setPropertyValue("ParaAdjust", 
uno::makeAny(style::ParagraphAdjust_CENTER));
 
     drawing::LineStyle eStyle = drawing::LineStyle_NONE;
     m_aLineProperties.LineStyle >>= eStyle;
@@ -220,13 +231,19 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
 
     xBroadcaster->lockBroadcasts();
 
+    auto* pTableObject = 
static_cast<sdr::table::SdrTableObj*>(m_xTableShape->GetSdrObject());
+
     bool bHBorder = false;
     bool bVBorder = false;
     bool bOutline = false;
+    bool bKeys = false;
+
+    std::vector<ViewLegendSymbol> aSymbols;
 
     m_xDataTableModel->getPropertyValue("HBorder") >>= bHBorder;
     m_xDataTableModel->getPropertyValue("VBorder") >>= bVBorder;
     m_xDataTableModel->getPropertyValue("Outline") >>= bOutline;
+    m_xDataTableModel->getPropertyValue("Keys") >>= bKeys;
 
     sal_Int32 nColumnCount = m_aXValues.size();
     uno::Reference<table::XTableColumns> xTableColumns = xTable->getColumns();
@@ -258,22 +275,52 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
         {
             xCellTextRange->setString(rString);
             bool bLeft = bOutline || (bVBorder && nColumn > 1);
-            setCellDefaults(xPropertySet, bLeft, bOutline, bOutline, bOutline);
+            setCellProperties(xPropertySet, bLeft, bOutline, bOutline, 
bOutline);
+            setCellCharAndParagraphProperties(xPropertySet);
         }
         nColumn++;
     }
 
+    if (bKeys)
+    {
+        awt::Size aMaxSymbolExtent(300, 300);
+        for (VSeriesPlotter* pSeriesPlotter : m_pSeriesPlotterList)
+        {
+            if (pSeriesPlotter)
+            {
+                uno::Reference<lang::XMultiServiceFactory> 
xFactory(m_xChartModel, uno::UNO_QUERY);
+                std::vector<ViewLegendSymbol> aNewEntries = 
pSeriesPlotter->createSymbols(
+                    aMaxSymbolExtent, m_xTarget, xFactory, 
m_xComponentContext);
+                aSymbols.insert(aSymbols.end(), aNewEntries.begin(), 
aNewEntries.end());
+            }
+        }
+    }
+
     nRow = 1;
     for (auto const& rSeriesName : m_aDataSeriesNames)
     {
         uno::Reference<table::XCell> xCell = xTable->getCellByPosition(0, 
nRow);
-        uno::Reference<beans::XPropertySet> xPropertySet(xCell, 
uno::UNO_QUERY);
+        uno::Reference<beans::XPropertySet> xCellPropertySet(xCell, 
uno::UNO_QUERY);
         uno::Reference<text::XTextRange> xCellTextRange(xCell, uno::UNO_QUERY);
         if (xCellTextRange.is())
         {
             bool bTop = bOutline || (bHBorder && nRow > 1);
-            xCellTextRange->setString(rSeriesName);
-            setCellDefaults(xPropertySet, bOutline, bTop, bOutline, bOutline);
+            setCellProperties(xCellPropertySet, bOutline, bTop, bOutline, 
bOutline);
+
+            auto xText = xCellTextRange->getText();
+            xText->insertString(xText->getStart(), rSeriesName, false);
+            uno::Reference<container::XEnumerationAccess> xEnumAccess(xText, 
uno::UNO_QUERY);
+            uno::Reference<container::XEnumeration> 
xEnumeration(xEnumAccess->createEnumeration());
+            uno::Reference<text::XTextRange> 
xParagraph(xEnumeration->nextElement(),
+                                                        uno::UNO_QUERY);
+            uno::Reference<beans::XPropertySet> xTextPropertySet(xParagraph, 
uno::UNO_QUERY);
+
+            setCellCharAndParagraphProperties(xTextPropertySet);
+
+            xCellPropertySet->setPropertyValue("ParaAdjust",
+                                               
uno::makeAny(style::ParagraphAdjust_LEFT));
+            if (bKeys)
+                xCellPropertySet->setPropertyValue("ParaLeftMargin", 
uno::makeAny(sal_Int32(500)));
         }
         nRow++;
     }
@@ -308,7 +355,8 @@ void DataTableView::createShapes(basegfx::B2DVector const& 
rStart, basegfx::B2DV
                 if (nColumn == nColumnCount && bOutline)
                     bRight = true;
 
-                setCellDefaults(xPropertySet, bLeft, bTop, bRight, bBottom);
+                setCellProperties(xPropertySet, bLeft, bTop, bRight, bBottom);
+                setCellCharAndParagraphProperties(xPropertySet);
             }
             nColumn++;
         }
@@ -317,20 +365,41 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
 
     xBroadcaster->unlockBroadcasts();
 
-    auto* pTableObject = 
static_cast<sdr::table::SdrTableObj*>(m_xTableShape->GetSdrObject());
     pTableObject->DistributeColumns(0, nColumnCount - 1, true, true);
+    pTableObject->DistributeRows(0, nRowCount - 1, true, true);
 
     uno::Reference<beans::XPropertySet> 
xPropertySet(xTableColumns->getByIndex(0), uno::UNO_QUERY);
     sal_Int32 nWidth = 0;
     xPropertySet->getPropertyValue("Width") >>= nWidth;
 
-    m_xTableShape->setPosition(
-        { basegfx::fround(rStart.getX() - nWidth), 
basegfx::fround(rStart.getY()) });
+    sal_Int32 nTableX = basegfx::fround(rStart.getX() - nWidth);
+    sal_Int32 nTableY = basegfx::fround(rStart.getY());
+    m_xTableShape->setPosition({ nTableX, nTableY });
 
     for (sal_Int32 i = 1; i < xTableColumns->getCount(); ++i)
     {
         xPropertySet.set(xTableColumns->getByIndex(i), uno::UNO_QUERY);
-        xPropertySet->setPropertyValue("Width", uno::Any(nColumnWidth));
+        xPropertySet->setPropertyValue("Width", uno::makeAny(nColumnWidth));
+    }
+
+    if (bKeys)
+    {
+        sal_Int32 nTotalHeight = 0;
+        for (sal_Int32 i = 0; i < xTableRows->getCount(); i++)
+        {
+            sal_Int32 nSymbolIndex = i - 1;
+            if (nSymbolIndex >= sal_Int32(aSymbols.size()))
+                continue;
+            xPropertySet.set(xTableRows->getByIndex(i), uno::UNO_QUERY);
+            sal_Int32 nHeight = 0;
+            xPropertySet->getPropertyValue("Height") >>= nHeight;
+            if (i > 0)
+            {
+                aSymbols[nSymbolIndex].aSymbol->setPosition(
+                    { nTableX + 100, nTableY + nTotalHeight + 100 });
+            }
+            nTotalHeight += nHeight;
+        }
     }
 }
 
@@ -344,6 +413,8 @@ void DataTableView::initializeValues(
 {
     for (auto& rSeriesPlotter : rSeriesPlotterList)
     {
+        m_pSeriesPlotterList.push_back(rSeriesPlotter.get());
+
         for (auto const& rCategory :
              
rSeriesPlotter->getExplicitCategoriesProvider()->getSimpleCategories())
         {
diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx
index 18497bcc2494..e71c8517bb3f 100644
--- a/include/svx/svdotable.hxx
+++ b/include/svx/svdotable.hxx
@@ -142,6 +142,8 @@ public:
     /** The active table has the focus or is currently edited */
     const sdr::table::CellRef& getActiveCell() const;
 
+    CellRef getCell(const CellPos& rPos) const;
+
     void setActiveCell( const sdr::table::CellPos& rPos );
     void getActiveCellPos( sdr::table::CellPos& rPos ) const;
     sal_Int32 getColumnCount() const;
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 28ad30df44b9..4ed1eaec2f60 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -1568,6 +1568,18 @@ void SdrTableObj::TakeTextRect( const CellPos& rPos, 
SdrOutliner& rOutliner, too
     rTextRect=tools::Rectangle(aTextPos,aTextSiz);
 }
 
+CellRef SdrTableObj::getCell(const CellPos& rPos) const
+{
+    if (mpImpl.is())
+    {
+        return mpImpl->getCell(rPos);
+    }
+    else
+    {
+        static CellRef xCell;
+        return xCell;
+    }
+}
 
 const CellRef& SdrTableObj::getActiveCell() const
 {

Reply via email to