include/xmloff/xmltoken.hxx | 1 sc/inc/dbdata.hxx | 2 sc/qa/unit/PivotTableFormatsImportExport.cxx | 35 ++++++- sc/qa/unit/data/ods/tdf162262_summarybelow.ods |binary sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx |binary sc/qa/unit/subsequent_export_test4.cxx | 30 ++++++ sc/source/core/data/table2.cxx | 50 ---------- sc/source/filter/excel/xepivotxml.cxx | 31 +++--- sc/source/filter/inc/stylesbuffer.hxx | 10 +- sc/source/filter/oox/stylesbuffer.cxx | 35 ++++++- sc/source/filter/oox/stylesfragment.cxx | 3 sc/source/filter/xml/XMLExportDatabaseRanges.cxx | 3 sc/source/filter/xml/xmldrani.cxx | 5 + sc/source/filter/xml/xmldrani.hxx | 2 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng | 9 + xmloff/source/core/xmltoken.cxx | 1 xmloff/source/token/tokens.txt | 1 17 files changed, 147 insertions(+), 71 deletions(-)
New commits: commit 9be630c709e4b4c50c74e2874181e118e40c956a Author: Balazs Varga <balazs.varga.ext...@allotropia.de> AuthorDate: Tue Nov 5 13:07:05 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed Nov 27 00:31:45 2024 +0100 Related tdf#162262 - sc: odf import/export of "Summary below data" Add new LO_EXT "summary-below" attribute for table:subtotal-rules. Follow up commit: 26c08356d1b2a963efdca570979cb04388371400 (tdf#162262 sc add "Summary below data" option for Subtotal dialog) Change-Id: Ie7f43d3c76479cd9468552b5939de5dbb2082a02 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176058 Tested-by: Jenkins Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177378 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Tested-by: allotropia jenkins <jenk...@allotropia.de> diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 20b1398201bd..e3b54f961206 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -1924,6 +1924,7 @@ namespace xmloff::token { XML_SUB_VIEW_SIZE, XML_SUFFIX, XML_SUM, + XML_SUMMARY_BELOW, XML_SWISS, XML_SYMBOL, XML_SYMBOL_HEIGHT, diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index c1164b064b17..532d71528e07 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -192,7 +192,7 @@ public: SC_DLLPUBLIC bool GetAdvancedQuerySource(ScRange& rSource) const; SC_DLLPUBLIC void SetAdvancedQuerySource(const ScRange* pSource); - void GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const; + SC_DLLPUBLIC void GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const; void SetSubTotalParam(const ScSubTotalParam& rSubTotalParam); void GetImportParam(ScImportParam& rImportParam) const; diff --git a/sc/qa/unit/data/ods/tdf162262_summarybelow.ods b/sc/qa/unit/data/ods/tdf162262_summarybelow.ods new file mode 100644 index 000000000000..bd2eeba48d01 Binary files /dev/null and b/sc/qa/unit/data/ods/tdf162262_summarybelow.ods differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index 19f148f9a0f0..dc5831f79e70 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -21,6 +21,8 @@ #include <postit.hxx> #include <validat.hxx> #include <scresid.hxx> +#include <dbdata.hxx> +#include <subtotalparam.hxx> #include <globstr.hrc> #include <tabprotection.hxx> #include <dpobject.hxx> @@ -394,6 +396,34 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf162262) assertXPath(pSheet, "/x:worksheet/x:sheetPr/x:outlinePr", "summaryBelow", u"0"_ustr); } +CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf162262_summarybelow) +{ + createScDoc("ods/tdf162262_summarybelow.ods"); + + ScDocument* pDoc = getScDoc(); + ScDBCollection* pDBCollection = pDoc->GetDBCollection(); + CPPUNIT_ASSERT(pDBCollection); + { + const ScDBData* pDBData = pDBCollection->GetDBAtArea(0, 0, 0, 1, 13); + CPPUNIT_ASSERT(pDBData); + ScSubTotalParam aParam; + pDBData->GetSubTotalParam(aParam); + CPPUNIT_ASSERT(!aParam.bSummaryBelow); + } + + saveAndReload(u"calc8"_ustr); + pDoc = getScDoc(); + pDBCollection = pDoc->GetDBCollection(); + CPPUNIT_ASSERT(pDBCollection); + { + const ScDBData* pDBData = pDBCollection->GetDBAtArea(0, 0, 0, 1, 13); + CPPUNIT_ASSERT(pDBData); + ScSubTotalParam aParam; + pDBData->GetSubTotalParam(aParam); + CPPUNIT_ASSERT(!aParam.bSummaryBelow); + } +} + CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf122331) { createScDoc("ods/tdf122331.ods"); diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx index 89ebcc27373c..7c28d5c81125 100644 --- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx +++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx @@ -655,6 +655,9 @@ private: if (aParam.bCaseSens) mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); + if (!aParam.bSummaryBelow) + mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_SUMMARY_BELOW, XML_FALSE); + SvXMLElementExport aElemSTRs(mrExport, XML_NAMESPACE_TABLE, XML_SUBTOTAL_RULES, true, true); if (aParam.bDoSort) diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx index 5708c74d2fa3..bfa6be8c898f 100644 --- a/sc/source/filter/xml/xmldrani.cxx +++ b/sc/source/filter/xml/xmldrani.cxx @@ -99,6 +99,7 @@ ScXMLDatabaseRangeContext::ScXMLDatabaseRangeContext( ScXMLImport& rImport, bSubTotalsBindFormatsToContent(false), bSubTotalsIsCaseSensitive(false), bSubTotalsInsertPageBreaks(false), + bSubTotalsSummaryBelow(true), bSubTotalsSortGroups(false), bSubTotalsEnabledUserList(false), bSubTotalsAscending(true), @@ -325,6 +326,7 @@ std::unique_ptr<ScDBData> ScXMLDatabaseRangeContext::ConvertToDBData(const OUStr aParam.bUserDef = bSubTotalsEnabledUserList; aParam.nUserIndex = nSubTotalsUserListIndex; aParam.bPagebreak = bSubTotalsInsertPageBreaks; + aParam.bSummaryBelow = bSubTotalsSummaryBelow; aParam.bCaseSens = bSubTotalsIsCaseSensitive; aParam.bDoSort = bSubTotalsSortGroups; aParam.bAscending = bSubTotalsAscending; @@ -634,6 +636,9 @@ ScXMLSubTotalRulesContext::ScXMLSubTotalRulesContext( ScXMLImport& rImport, case XML_ELEMENT( TABLE, XML_PAGE_BREAKS_ON_GROUP_CHANGE ): pDatabaseRangeContext->SetSubTotalsInsertPageBreaks(IsXMLToken(aIter, XML_TRUE)); break; + case XML_ELEMENT( LO_EXT, XML_SUMMARY_BELOW ): + pDatabaseRangeContext->SetSubTotalsSummaryBelow(IsXMLToken(aIter, XML_TRUE)); + break; } } } diff --git a/sc/source/filter/xml/xmldrani.hxx b/sc/source/filter/xml/xmldrani.hxx index a35074117c28..4f5b951751c1 100644 --- a/sc/source/filter/xml/xmldrani.hxx +++ b/sc/source/filter/xml/xmldrani.hxx @@ -76,6 +76,7 @@ class ScXMLDatabaseRangeContext : public ScXMLImportContext bool bSubTotalsBindFormatsToContent; bool bSubTotalsIsCaseSensitive; bool bSubTotalsInsertPageBreaks; + bool bSubTotalsSummaryBelow; bool bSubTotalsSortGroups; bool bSubTotalsEnabledUserList; bool bSubTotalsAscending; @@ -106,6 +107,7 @@ public: void SetSubTotalsBindFormatsToContent(const bool bTemp ) { bSubTotalsBindFormatsToContent = bTemp; } void SetSubTotalsIsCaseSensitive(const bool bTemp) { bSubTotalsIsCaseSensitive = bTemp; } void SetSubTotalsInsertPageBreaks(const bool bTemp) { bSubTotalsInsertPageBreaks = bTemp; } + void SetSubTotalsSummaryBelow(const bool bTemp) { bSubTotalsSummaryBelow = bTemp; } void SetSubTotalsEnabledUserList(const bool bTemp) { bSubTotalsEnabledUserList = bTemp; } void SetSubTotalsUserListIndex(const sal_Int16 nTemp) { nSubTotalsUserListIndex = nTemp; } void SetSubTotalsAscending(const bool bTemp) { bSubTotalsAscending = bTemp; } diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng index 86f4322929c4..c9d41d0778cd 100644 --- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng @@ -2727,6 +2727,15 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:optional> </rng:define> + <!-- TODO no proposal, tdf#162262 --> + <rng:define name="table-subtotal-rules-attlist" combine="interleave"> + <rng:optional> + <rng:attribute name="loext:summary-below"> + <rng:ref name="boolean"/> + </rng:attribute> + </rng:optional> + </rng:define> + <!-- TODO no proposal, 9009663d --> <rng:define name="chart-chart-attlist" combine="interleave"> <rng:optional> diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 467713fda6ec..171c38c9ac45 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -1937,6 +1937,7 @@ namespace xmloff::token { TOKEN( "sub-view-size", XML_SUB_VIEW_SIZE ), TOKEN( "suffix", XML_SUFFIX ), TOKEN( "sum", XML_SUM ), + TOKEN( "summary-below", XML_SUMMARY_BELOW ), TOKEN( "swiss", XML_SWISS ), TOKEN( "symbol", XML_SYMBOL ), TOKEN( "symbol-height", XML_SYMBOL_HEIGHT ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 25cdb87ed5b4..9bfe5dda2b8c 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -1837,6 +1837,7 @@ subtotal-rules sub-view-size suffix sum +summary-below swiss symbol symbol-height commit de0f01eb163b258b04fd97b6a78817afc0c7fe46 Author: Balazs Varga <balazs.varga.ext...@allotropia.de> AuthorDate: Thu Nov 21 00:53:28 2024 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed Nov 27 00:31:31 2024 +0100 Related: tdf#160536 - ooxml import export correctly cell protection property for Pivot tables cells. Change-Id: I1bff7a27cf169fd0876e361b22b4d7017f190b40 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176897 Tested-by: Jenkins Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177233 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Tested-by: allotropia jenkins <jenk...@allotropia.de> diff --git a/sc/qa/unit/PivotTableFormatsImportExport.cxx b/sc/qa/unit/PivotTableFormatsImportExport.cxx index 22d56c0f11d6..437a25d5e7e6 100644 --- a/sc/qa/unit/PivotTableFormatsImportExport.cxx +++ b/sc/qa/unit/PivotTableFormatsImportExport.cxx @@ -57,6 +57,13 @@ Color getFontColor(ScDocument& rDoc, OUString const& rAddressString) return rItem.getColor(); } +bool getCellProtection(ScDocument& rDoc, OUString const& rAddressString) +{ + const ScPatternAttr* pPattern = rDoc.GetPattern(parseAddress(rDoc, rAddressString)); + const ScProtectionAttr& rItem = pPattern->GetItem(ATTR_PROTECTION); + return rItem.GetProtection(); +} + template <typename T> OUString checkNonEmptyAddresses(ScDocument& rDoc, T const& rArrayOfAddresses) { OUString aString; @@ -66,7 +73,8 @@ template <typename T> OUString checkNonEmptyAddresses(ScDocument& rDoc, T const& aAddress.Parse(rAddressString, rDoc); const ScPatternAttr* pPattern = rDoc.GetPattern(aAddress); if (pPattern->GetItem(ATTR_FONT_COLOR).getColor() != COL_BLACK - || pPattern->GetItem(ATTR_BACKGROUND).GetColor() != COL_TRANSPARENT) + || pPattern->GetItem(ATTR_BACKGROUND).GetColor() != COL_TRANSPARENT + || !pPattern->GetItem(ATTR_PROTECTION).GetProtection()) { aString += rAddressString + " "; } @@ -416,6 +424,31 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, assertTwoDataFieldColumns_WholeDataColumnSelected(*getScDoc()); } +static void assertFields_WithCellProtection(ScDocument& rDoc) +{ + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F18"_ustr)); + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F19"_ustr)); + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"F20"_ustr)); + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G18"_ustr)); + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G19"_ustr)); + CPPUNIT_ASSERT_EQUAL(false, getCellProtection(rDoc, u"G20"_ustr)); + + // Make sure the other cells have the font color or background set to default + std::vector<OUString> aEmptyAddresses{ + u"F15"_ustr, u"G15"_ustr, u"F16"_ustr, u"G16"_ustr, + u"F17"_ustr, u"G17"_ustr, u"G21"_ustr, u"F21"_ustr, + }; + CPPUNIT_ASSERT_EQUAL(OUString(), checkNonEmptyAddresses(rDoc, aEmptyAddresses)); +} + +CPPUNIT_TEST_FIXTURE(ScPivotTableFormatsImportExport, Pivot_Table_with_Cell_Protection) +{ + createScDoc("xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx"); + assertFields_WithCellProtection(*getScDoc()); + saveAndReload(u"Calc Office Open XML"_ustr); + assertFields_WithCellProtection(*getScDoc()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx b/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx new file mode 100644 index 000000000000..d7966a2d9e32 Binary files /dev/null and b/sc/qa/unit/data/xlsx/pivot-table/Pivot_Table_with_Cell_Protection.xlsx differ diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 4321a27893a5..83a880bdaf3b 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -433,20 +433,6 @@ void ScTable::DeleteArea( aCol[i].DeleteArea(nRow1, nRow2, nDelFlag, bBroadcast, pBroadcastSpans); } - // Do not set protected cell in a protected table - - if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) ) - { - // Do not overwrite cell protection if we are in a Pivot table area and its not protected - const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab, nCol1, nRow1, nCol2, nRow2); - if (!pDPObj || (pDPObj && !GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES))) - { - ScPatternAttr aPattern(rDocument.getCellAttributeHelper()); - aPattern.GetItemSet().Put(ScProtectionAttr(false)); - ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern); - } - } - if( nDelFlag & InsertDeleteFlags::ATTRIB ) mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 ); } @@ -475,28 +461,6 @@ void ScTable::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMa mpCondFormatList->DeleteArea( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row() ); } - // Do not set protected cell in a protected sheet - - if ( IsProtected() && (nDelFlag & InsertDeleteFlags::ATTRIB) ) - { - // Do not overwrite cell protection if we are in a Pivot table area and its not protected - const ScRange& rRange = rMark.GetArea(); - const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab, - rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()); - if (!pDPObj || (pDPObj && !GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES))) - { - SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aSet(*rDocument.GetPool()); - aSet.Put(ScProtectionAttr(false)); - ScItemPoolCache aCache(rDocument.getCellAttributeHelper(), aSet); - ApplySelectionCache(aCache, rMark); - } - - SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aSet(*rDocument.GetPool()); - aSet.Put( ScProtectionAttr( false ) ); - ScItemPoolCache aCache(rDocument.getCellAttributeHelper(), aSet ); - ApplySelectionCache( aCache, rMark ); - } - // TODO: In the future we may want to check if the table has been // really modified before setting the stream invalid. SetStreamValid(false); @@ -787,20 +751,6 @@ void ScTable::CopyFromClip( pRowFlags->AndValue( j, ~CRFlags::ManualSize); } } - - // Do not set protected cell in a protected sheet - if (IsProtected() && (rCxt.getInsertFlag() & InsertDeleteFlags::ATTRIB)) - { - // Do not overwrite cell protection if we are in a Pivot table area and its not protected - const ScDPObject* pDPObj = rDocument.GetDPAtArea(nTab, nCol1, nRow1, nCol2, nRow2); - if (!pDPObj || (pDPObj && !GetProtection()->isOptionEnabled(ScTableProtection::PIVOT_TABLES))) - { - ScPatternAttr aPattern(rDocument.getCellAttributeHelper()); - aPattern.GetItemSet().Put(ScProtectionAttr(false)); - ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern); - } - } - // create deep copies for conditional formatting CopyConditionalFormat( nCol1, nRow1, nCol2, nRow2, nDx, nDy, pTable); } diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx index ddccb1cd36f6..90f58aebc574 100644 --- a/sc/source/filter/excel/xepivotxml.cxx +++ b/sc/source/filter/excel/xepivotxml.cxx @@ -1241,25 +1241,28 @@ void XclExpXmlPivotTables::savePivotTableFormats(XclExpXmlStream& rStream, ScDPO pAttributeList->add(XML_fieldPosition, OString::number(*rFormat.oFieldPosition)); pPivotStream->startElement(XML_pivotArea, pAttributeList); } - pPivotStream->startElement(XML_references, XML_count, OString::number(rFormat.aSelections.size())); - for (sc::Selection const& rSelection : rFormat.getSelections()) + if (rFormat.aSelections.size()) { + pPivotStream->startElement(XML_references, XML_count, OString::number(rFormat.aSelections.size())); + for (sc::Selection const& rSelection : rFormat.getSelections()) { - auto pRefAttributeList = sax_fastparser::FastSerializerHelper::createAttrList(); - pRefAttributeList->add(XML_field, OString::number(sal_uInt32(rSelection.nField))); - pRefAttributeList->add(XML_count, "1"); - if (!rSelection.bSelected) // default is true - pRefAttributeList->add(XML_selected, "0"); - pPivotStream->startElement(XML_reference, pRefAttributeList); - } + { + auto pRefAttributeList = sax_fastparser::FastSerializerHelper::createAttrList(); + pRefAttributeList->add(XML_field, OString::number(sal_uInt32(rSelection.nField))); + pRefAttributeList->add(XML_count, "1"); + if (!rSelection.bSelected) // default is true + pRefAttributeList->add(XML_selected, "0"); + pPivotStream->startElement(XML_reference, pRefAttributeList); + } - for (sal_uInt32 nIndex : rSelection.nIndices) - { - pPivotStream->singleElement(XML_x, XML_v, OString::number(nIndex)); + for (sal_uInt32 nIndex : rSelection.nIndices) + { + pPivotStream->singleElement(XML_x, XML_v, OString::number(nIndex)); + } + pPivotStream->endElement(XML_reference); } - pPivotStream->endElement(XML_reference); + pPivotStream->endElement(XML_references); } - pPivotStream->endElement(XML_references); pPivotStream->endElement(XML_pivotArea); pPivotStream->endElement(XML_format); diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx index ec6f5800cb66..95ec8b8806ff 100644 --- a/sc/source/filter/inc/stylesbuffer.hxx +++ b/sc/source/filter/inc/stylesbuffer.hxx @@ -357,11 +357,14 @@ bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight class Protection : public WorkbookHelper { public: - explicit Protection( const WorkbookHelper& rHelper ); + explicit Protection( const WorkbookHelper& rHelper, bool bDxf ); /** Sets all attributes from the protection element. */ void importProtection( const AttributeList& rAttribs ); + /** Sets the protection attributes from the passed BIFF12 DXF record data. */ + void importDxfProtection( sal_Int32 nElement, SequenceInputStream& rStrm ); + /** Sets the protection attributes from the passed BIFF12 XF record data. */ void setBiff12Data( sal_uInt32 nFlags ); @@ -375,8 +378,11 @@ public: private: ProtectionModel maModel; /// Protection model data. ApiProtectionData maApiData; /// Protection data converted to API constants. + bool mbDxf; }; +typedef std::shared_ptr< Protection > ProtectionRef; + /** Contains XML attributes of a single border line. */ struct BorderLineModel { @@ -667,6 +673,8 @@ public: BorderRef const & createBorder( bool bAlwaysNew = true ); /** Creates a new empty fill object. */ FillRef const & createFill( bool bAlwaysNew = true ); + /** Creates a new empty protection object. */ + ProtectionRef const & createProtection( bool bAlwaysNew = true ); /** Inserts a new number format code. */ void importNumFmt( const AttributeList& rAttribs ); diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index 5f64cf61addb..efdca05255e5 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -183,6 +183,8 @@ const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36; const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37; const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38; const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41; +const sal_uInt16 BIFF12_DXF_CELL_LOCKED = 43; +const sal_uInt16 BIFF12_DXF_CELL_HIDDEN = 44; // BIFF12 CELLSTYLE flags const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001; @@ -1368,8 +1370,9 @@ bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden); } -Protection::Protection( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ) +Protection::Protection( const WorkbookHelper& rHelper, bool bDxf ) : + WorkbookHelper( rHelper ), + mbDxf( bDxf ) { } @@ -1379,6 +1382,23 @@ void Protection::importProtection( const AttributeList& rAttribs ) maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); } +void Protection::importDxfProtection( sal_Int32 nElement, SequenceInputStream& rStrm ) +{ + SAL_WARN_IF( !mbDxf, "sc", "Protection::importDxfProtection - missing protection flag" ); + bool bFlag = rStrm.readuInt8() != 0; + switch( nElement ) + { + case XML_locked: + maModel.mbLocked = bFlag; + break; + case XML_hidden: + maModel.mbHidden = bFlag; + break; + default: + OSL_FAIL( "Protection::importDxfProtection - unexpected element identifier" ); + } +} + void Protection::setBiff12Data( sal_uInt32 nFlags ) { maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED ); @@ -2005,7 +2025,7 @@ Xf::Xf( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), mnScNumFmt(0), maAlignment( rHelper ), - maProtection( rHelper ), + maProtection( rHelper, false ), meRotationRef( css::table::CellVertJustify2::STANDARD ), mpStyleSheet( nullptr ) { @@ -2341,6 +2361,13 @@ FillRef const & Dxf::createFill( bool bAlwaysNew ) return mxFill; } +ProtectionRef const & Dxf::createProtection( bool bAlwaysNew ) +{ + if ( bAlwaysNew || !mxProtection ) + mxProtection = std::make_shared<Protection>( *this, true ); + return mxProtection; +} + void Dxf::importNumFmt( const AttributeList& rAttribs ) { // don't propagate number formats defined in Dxf entries @@ -2391,6 +2418,8 @@ void Dxf::importDxf( SequenceInputStream& rStrm ) case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break; case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break; case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break; + case BIFF12_DXF_CELL_LOCKED: createProtection( false )->importDxfProtection( XML_locked, rStrm ); break; + case BIFF12_DXF_CELL_HIDDEN: createProtection( false )->importDxfProtection( XML_hidden, rStrm ); break; } rStrm.seek( nRecEnd ); } diff --git a/sc/source/filter/oox/stylesfragment.cxx b/sc/source/filter/oox/stylesfragment.cxx index de6312b9649c..1d20b98519ff 100644 --- a/sc/source/filter/oox/stylesfragment.cxx +++ b/sc/source/filter/oox/stylesfragment.cxx @@ -151,8 +151,8 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const Attribu case XLS_TOKEN( numFmt ): mxDxf->importNumFmt( rAttribs ); break; #if 0 case XLS_TOKEN( alignment ): mxDxf->importAlignment( rAttribs ); break; - case XLS_TOKEN( protection ): mxDxf->importProtection( rAttribs ); break; #endif + case XLS_TOKEN( protection ): mxDxf->createProtection()->importProtection( rAttribs ); break; } break; @@ -163,6 +163,7 @@ 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; + case XLS_TOKEN( protection ): mxDxf->createProtection()->importProtection( rAttribs ); break; } break; }