sc/inc/pivot/PivotTableFormats.hxx                                             
      |    2 
 sc/qa/unit/PivotTableFormatsImportExport.cxx                                   
      |   15 +
 
sc/qa/unit/data/xlsx/pivot-table/PivotTableCellFormatsTest_9_MultipleSelections.xlsx
 |binary
 sc/source/core/data/PivotTableFormatOutput.cxx                                 
      |   82 +++++-----
 sc/source/filter/excel/xepivotxml.cxx                                          
      |    6 
 sc/source/filter/oox/PivotTableFormat.cxx                                      
      |    2 
 6 files changed, 69 insertions(+), 38 deletions(-)

New commits:
commit ded4d570fde21e55091c9c8c364114e67aa0cdcf
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Apr 16 00:39:20 2024 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Apr 16 08:31:38 2024 +0200

    pivot: suppprt multiple cell format reference indices
    
    This adds support for multiple cell format reference indices, so
    the same cell format is applied to multiple cells (defined by
    indices) so that each doesn't need to be defined by its own
    reference (as they are all the same anyway and only differ by
    single index).
    
    The solution is to create multiple format outputs for one format
    entry - each for a selection index, but have other data still the
    same. This is a bit tricky as previously it was one format output
    for one format entry, which is not the case anymore.
    
    Change-Id: I074ac03e7d81e26562a6a6cc395b11cfed16766d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166131
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sc/inc/pivot/PivotTableFormats.hxx 
b/sc/inc/pivot/PivotTableFormats.hxx
index 8c8ebcadffbd..d569c6167e1f 100644
--- a/sc/inc/pivot/PivotTableFormats.hxx
+++ b/sc/inc/pivot/PivotTableFormats.hxx
@@ -29,7 +29,7 @@ struct Selection
 {
     bool bSelected = false;
     sal_Int32 nField = 0;
-    sal_uInt32 nDataIndex = 0;
+    std::vector<sal_uInt32> nIndices;
 };
 
 /** Holds cell pattern attributes and a selection information to which cells 
in the pivot table
diff --git a/sc/qa/unit/PivotTableFormatsImportExport.cxx 
b/sc/qa/unit/PivotTableFormatsImportExport.cxx
index 1c20cdc3b5ac..40db2afb2292 100644
--- a/sc/qa/unit/PivotTableFormatsImportExport.cxx
+++ b/sc/qa/unit/PivotTableFormatsImportExport.cxx
@@ -295,6 +295,21 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
     assertDocument(*getScDoc());
 }
 
+CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport,
+                     PivotTableCellFormatsTest_9_MultipleSelections)
+{
+    auto assertDocument = [](ScDocument& rDoc) {
+        CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I6"_ustr));
+        CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I7"_ustr));
+        CPPUNIT_ASSERT_EQUAL(COL_YELLOW, getBackgroundColor(rDoc, u"I8"_ustr));
+    };
+
+    
createScDoc("xlsx/pivot-table/PivotTableCellFormatsTest_9_MultipleSelections.xlsx");
+    assertDocument(*getScDoc());
+    saveAndReload("Calc Office Open XML");
+    assertDocument(*getScDoc());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/sc/qa/unit/data/xlsx/pivot-table/PivotTableCellFormatsTest_9_MultipleSelections.xlsx
 
b/sc/qa/unit/data/xlsx/pivot-table/PivotTableCellFormatsTest_9_MultipleSelections.xlsx
new file mode 100644
index 000000000000..6d317d2e45c0
Binary files /dev/null and 
b/sc/qa/unit/data/xlsx/pivot-table/PivotTableCellFormatsTest_9_MultipleSelections.xlsx
 differ
diff --git a/sc/source/core/data/PivotTableFormatOutput.cxx 
b/sc/source/core/data/PivotTableFormatOutput.cxx
index 9f6dcf2355b7..fbef219b513b 100644
--- a/sc/source/core/data/PivotTableFormatOutput.cxx
+++ b/sc/source/core/data/PivotTableFormatOutput.cxx
@@ -84,7 +84,7 @@ void initLines(std::vector<LineData>& rLines, 
std::vector<ScDPOutLevelData> cons
     }
 }
 
-void initFormatOutputField(std::vector<FormatOutputField>& rOutputFields,
+void initFormatOutputField(size_t nSelectionIndex, 
std::vector<FormatOutputField>& rOutputFields,
                            std::vector<ScDPOutLevelData> const& rFields,
                            PivotTableFormat const& rFormat, NameResolver& 
rNameResolver)
 {
@@ -99,19 +99,18 @@ void initFormatOutputField(std::vector<FormatOutputField>& 
rOutputFields,
         {
             if (rSelection.nField == rOutputField.nDimension)
             {
+                if (rSelection.nIndices.size() > 1)
+                    rOutputField.nIndex = rSelection.nIndices[nSelectionIndex];
+                else
+                    rOutputField.nIndex = rSelection.nIndices[0];
+
                 if (rOutputField.nDimension == -2)
-                {
                     rOutputField.aName = "DATA";
-                    rOutputField.nIndex = rSelection.nDataIndex;
-                    rOutputField.bSet = true;
-                }
                 else
-                {
                     rOutputField.aName
-                        = rNameResolver.getNameForIndex(rSelection.nDataIndex, 
rSelection.nField);
-                    rOutputField.nIndex = rSelection.nDataIndex;
-                    rOutputField.bSet = true;
-                }
+                        = rNameResolver.getNameForIndex(rOutputField.nIndex, 
rSelection.nField);
+
+                rOutputField.bSet = true;
             }
         }
     }
@@ -152,41 +151,56 @@ void FormatOutput::prepare(SCTAB nTab, 
std::vector<ScDPOutLevelData> const& rCol
     // Initialize format output entries (FormatOutputEntry) and set the data 
already available from output fields
     // (rColumnFields and rRowFields) and the pivot table format list 
(PivotTableFormat).
 
-    maFormatOutputEntries.resize(mpFormats->size());
-
-    size_t nFormatIndex = 0;
     for (PivotTableFormat const& rFormat : mpFormats->getVector())
     {
-        sc::FormatOutputEntry& rEntry = maFormatOutputEntries[nFormatIndex];
-        rEntry.pPattern = rFormat.pPattern;
-        rEntry.onTab = nTab;
-        rEntry.eType = rFormat.eType;
+        size_t nMaxNumberOfIndices = 1;
+        for (auto const& rSelection : rFormat.aSelections)
+        {
+            if (rSelection.nIndices.size() > 1)
+                nMaxNumberOfIndices = rSelection.nIndices.size();
+        }
 
-        initFormatOutputField(rEntry.aRowOutputFields, rRowFields, rFormat, 
aNameResolver);
+        if (nMaxNumberOfIndices == 0)
+            continue;
 
-        // If column fields list is empty, but there is a data field in 
columns that is not part of column fields
-        if (rColumnFields.size() == 0 && bColumnFieldIsDataOnly)
+        for (size_t nSelectionIndex = 0; nSelectionIndex < 
nMaxNumberOfIndices; nSelectionIndex++)
         {
-            // Initialize column output fields to have 1 data output field
-            rEntry.aColumnOutputFields.resize(1);
-            FormatOutputField& rOutputField = rEntry.aColumnOutputFields[0];
+            sc::FormatOutputEntry aEntry;
+            aEntry.pPattern = rFormat.pPattern;
+            aEntry.onTab = nTab;
+            aEntry.eType = rFormat.eType;
 
-            for (auto const& rSelection : rFormat.aSelections)
+            initFormatOutputField(nSelectionIndex, aEntry.aRowOutputFields, 
rRowFields, rFormat,
+                                  aNameResolver);
+
+            // If column fields list is empty, but there is a data field in 
columns that is not part of column fields
+            if (rColumnFields.size() == 0 && bColumnFieldIsDataOnly)
             {
-                if (rSelection.nField == -2)
+                // Initialize column output fields to have 1 data output field
+                aEntry.aColumnOutputFields.resize(1);
+                FormatOutputField& rOutputField = 
aEntry.aColumnOutputFields[0];
+
+                for (auto const& rSelection : rFormat.aSelections)
                 {
-                    rOutputField.aName = "DATA";
-                    rOutputField.nIndex = rSelection.nDataIndex;
-                    rOutputField.bSet = true;
+                    if (rSelection.nField == -2)
+                    {
+                        if (rSelection.nIndices.size() > 1)
+                            rOutputField.nIndex = 
rSelection.nIndices[nSelectionIndex];
+                        else
+                            rOutputField.nIndex = rSelection.nIndices[0];
+                        rOutputField.aName = "DATA";
+                        rOutputField.bSet = true;
+                    }
                 }
             }
+            else
+            {
+                initFormatOutputField(nSelectionIndex, 
aEntry.aColumnOutputFields, rColumnFields,
+                                      rFormat, aNameResolver);
+            }
+
+            maFormatOutputEntries.push_back(aEntry);
         }
-        else
-        {
-            initFormatOutputField(rEntry.aColumnOutputFields, rColumnFields, 
rFormat,
-                                  aNameResolver);
-        }
-        nFormatIndex++;
     }
 }
 
diff --git a/sc/source/filter/excel/xepivotxml.cxx 
b/sc/source/filter/excel/xepivotxml.cxx
index 81f1c71f30a6..3cb4bcf35b26 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -1253,8 +1253,10 @@ void 
XclExpXmlPivotTables::savePivotTableFormats(XclExpXmlStream& rStream, ScDPO
                         pPivotStream->startElement(XML_reference, 
pRefAttributeList);
                     }
 
-                    pPivotStream->singleElement(XML_x, XML_v, 
OString::number(rSelection.nDataIndex));
-
+                    for (sal_uInt32 nIndex : rSelection.nIndices)
+                    {
+                        pPivotStream->singleElement(XML_x, XML_v, 
OString::number(nIndex));
+                    }
                     pPivotStream->endElement(XML_reference);
                 }
                 pPivotStream->endElement(XML_references);
diff --git a/sc/source/filter/oox/PivotTableFormat.cxx 
b/sc/source/filter/oox/PivotTableFormat.cxx
index 870a6c99fad9..59626f89a527 100644
--- a/sc/source/filter/oox/PivotTableFormat.cxx
+++ b/sc/source/filter/oox/PivotTableFormat.cxx
@@ -110,7 +110,7 @@ void PivotTableFormat::finalizeImport()
             aFormat.aSelections.push_back(
                 sc::Selection{ .bSelected = rReference->mbSelected,
                                .nField = sal_Int32(*rReference->mnField),
-                               .nDataIndex = 
rReference->maFieldItemsIndices[0] });
+                               .nIndices = rReference->maFieldItemsIndices });
         }
     }
     aFormats.add(aFormat);

Reply via email to