tdf#122473 - Import alignment and axis-based pivot area formats

Change-Id: I2b90187d8e6e9788cc37320dff9035f2042b30f8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/210016
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Tested-by: Jenkins
This commit is contained in:
Andreas Heinisch
2026-09-07 07:58:38 +02:00
parent f4ce2515f8
commit 766e4da2bb
7 changed files with 63 additions and 4 deletions
@@ -15,6 +15,7 @@
#include <document.hxx>
#include <dpobject.hxx>
#include <attrib.hxx>
#include <scitems.hxx>
#include <globstr.hrc>
#include <scresid.hxx>
#include <rtl/string.hxx>
@@ -408,6 +409,34 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, testPivotTableFormatsSubTo
checkFormats();
}
CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, testTdf122473_PivotTableLabelRotation)
{
// Contains a pivotTable with differential formatting (dxf) and direct formatting
// with only an <alignment> child (textRotation) applied to two row-label cells
// ("Sum of C" rotated 90° and "Sum of D" set to stacked/vertical text).
createScDoc("xlsx/pivot-table/tdf122473_PivotTableLabelRotation.xlsx");
auto checkFormats = [this]() {
ScDocument& rDocument = *getScDoc();
// Without the fix in place, this test would have failed with
// - Expected: 9000
// - Actual : 0
// "Sum of C" row label at F9 -> dxf 0: textRotation="90"
CPPUNIT_ASSERT_EQUAL(Degree100(9000).get(),
rDocument.GetAttr(5, 8, 0, ATTR_ROTATE_VALUE).GetValue().get());
// Without the fix in place, this test would have failed with
// - Expected: 1
// - Actual : 0
// "Sum of D" row label at F10 -> dxf 1: textRotation="255" (stacked/vertical)
CPPUNIT_ASSERT_EQUAL(true, rDocument.GetAttr(5, 9, 0, ATTR_STACKED).GetValue());
};
checkFormats();
saveAndReload(TestFilter::XLSX);
checkFormats();
}
} // end anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
+2 -1
View File
@@ -51,7 +51,8 @@ private:
bool mbOutline = true;
std::optional<OUString> moOffset = std::nullopt;
bool mbCollapsedLevelsAreSubtotals = false;
// TODO Axis
// tdf#122473 - import alignment and axis-based pivot area formats
std::optional<sal_Int32> moAxis = std::nullopt;
std::optional<sal_uInt32> moFieldPosition = std::nullopt;
std::vector<std::shared_ptr<PivotTableReference>> maReferences;
+5
View File
@@ -339,6 +339,9 @@ private:
ApiAlignmentData maApiData; /// Alignment data converted to API constants.
};
// tdf#122473 - import alignment and axis-based pivot area formats
typedef std::shared_ptr<Alignment> AlignmentRef;
/** Contains all XML cell protection attributes, e.g. from a protection element. */
struct ProtectionModel
{
@@ -705,6 +708,8 @@ public:
BorderRef const & createBorder( bool bAlwaysNew = true );
/** Creates a new empty fill object. */
FillRef const & createFill( bool bAlwaysNew = true );
/** Creates a new empty alignment object. */
AlignmentRef const& createAlignment(bool bAlwaysNew = true);
/** Creates a new empty protection object. */
ProtectionRef const & createProtection( bool bAlwaysNew = true );
+15
View File
@@ -12,6 +12,7 @@
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
#include <pivot/PivotTableFormats.hxx>
#include <pivot/PivotTableFormatOutput.hxx>
#include <dpsave.hxx>
#include <dpobject.hxx>
@@ -72,6 +73,8 @@ void PivotTableFormat::importPivotArea(const oox::AttributeList& rAttribs)
moOffset = rAttribs.getXString(XML_offset);
mbCollapsedLevelsAreSubtotals = rAttribs.getBool(XML_collapsedLevelsAreSubtotals, false);
moFieldPosition = rAttribs.getUnsigned(XML_fieldPosition);
// tdf#122473 - import alignment and axis-based pivot area formats
moAxis = rAttribs.getToken(XML_axis);
}
void PivotTableFormat::finalizeImport()
@@ -146,6 +149,18 @@ void PivotTableFormat::finalizeImport()
.bHasSubtotal = bHasSubtotal });
}
}
// tdf#122473 - import alignment and axis-based pivot area formats
// There is no field or reference given. However, there exists an axis value.
// The format uses it to identify the label of the field data. Treat it as an
// explicit reference to the values field.
if (maReferences.empty() && mbLabelOnly && moAxis && *moAxis == XML_axisValues)
{
aFormat.aSelections.push_back(sc::Selection{ .bSelected = true,
.nField = sal_Int32(sc::constDataDimension),
.nIndices = {},
.bHasSubtotal = false });
}
aFormats.add(aFormat);
pSaveData->setFormats(aFormats);
+8
View File
@@ -2453,6 +2453,14 @@ FillRef const & Dxf::createFill( bool bAlwaysNew )
return mxFill;
}
// tdf#122473 - import alignment and axis-based pivot area formats
AlignmentRef const& Dxf::createAlignment(bool bAlwaysNew)
{
if (bAlwaysNew || !mxAlignment)
mxAlignment = std::make_shared<Alignment>(*this);
return mxAlignment;
}
ProtectionRef const & Dxf::createProtection( bool bAlwaysNew )
{
if ( bAlwaysNew || !mxProtection )
+4 -3
View File
@@ -149,9 +149,8 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const Attribu
case XLS_TOKEN( fill ): return new FillContext( *this, mxDxf->createFill() );
case XLS_TOKEN( numFmt ): mxDxf->importNumFmt( rAttribs ); break;
#if 0
case XLS_TOKEN( alignment ): mxDxf->importAlignment( rAttribs ); break;
#endif
// tdf#122473 - import alignment and axis-based pivot area formats
case XLS_TOKEN(alignment): mxDxf->createAlignment()->importAlignment(rAttribs); break;
case XLS_TOKEN( protection ): mxDxf->createProtection()->importProtection( rAttribs ); break;
}
break;
@@ -163,6 +162,8 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const Attribu
case XLS_TOKEN( border ): return new BorderContext( *this, mxDxf->createBorder() );
case XLS_TOKEN( fill ): return new FillContext( *this, mxDxf->createFill() );
case XLS_TOKEN( numFmt ): mxDxf->importNumFmt( rAttribs ); break;
// tdf#122473 - import alignment and axis-based pivot area formats
case XLS_TOKEN(alignment): mxDxf->createAlignment()->importAlignment(rAttribs); break;
case XLS_TOKEN( protection ): mxDxf->createProtection()->importProtection( rAttribs ); break;
}
break;