cui/source/options/optchart.cxx | 65 +++++++--- include/oox/core/filterdetect.hxx | 1 officecfg/registry/data/org/openoffice/TypeDetection/UISort.xcu | 2 oox/source/core/filterdetect.cxx | 55 ++++++++ sc/inc/scextopt.hxx | 1 sc/qa/unit/subsequent_export_test2.cxx | 32 ++++ sc/source/filter/excel/excdoc.cxx | 12 + sc/source/filter/inc/workbooksettings.hxx | 5 sc/source/filter/oox/workbookfragment.cxx | 1 sc/source/filter/oox/workbooksettings.cxx | 16 ++ 10 files changed, 162 insertions(+), 28 deletions(-)
New commits: commit b89190783eca21c16b4406e5d825c4bc51ecad84 Author: Jim Raykowski <[email protected]> AuthorDate: Tue Dec 9 11:12:48 2025 -0900 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Dec 16 16:48:28 2025 +0100 related tdf#163347 Improve sync color table to chart colors list ...entry selection * 'Custom', 'Theme colors', and 'Document colors' palettes are included in the search. * When no palette is found having the chart colors list entry selection color, the palette combobox text is set empty and the color valueset is cleared. This can happen when a chart colors list entry selection color was made from the 'Theme colors' palette and the SvxDefaultColorOptPage is opened from the start center backing window. Change-Id: I8ad9956c0bb9ee7de5fdcff77a250e81d7a58a9b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195335 Reviewed-by: Jim Raykowski <[email protected]> Tested-by: Jenkins (cherry picked from commit 7c836d8722a032ebc586a709659dffb15cbf84a6) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195545 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/cui/source/options/optchart.cxx b/cui/source/options/optchart.cxx index e90b7289c31c..bd99a339d2cf 100644 --- a/cui/source/options/optchart.cxx +++ b/cui/source/options/optchart.cxx @@ -99,26 +99,55 @@ IMPL_LINK_NOARG(SvxDefaultColorOptPage, LbChartColorsSelectionChangedHdl, weld:: Color& rColor(aColorList[nIndex]); XColorListRef xColorList; - for (size_t i = 0, nSize = aPaletteManager.GetPaletteList().size(); i < nSize; ++i) + for (sal_uInt16 nPalettePos = 0, nPaletteCount = aPaletteManager.GetPaletteCount(); + nPalettePos < nPaletteCount; ++nPalettePos) { - aPaletteManager.SetPalette(i, true/*bPosOnly*/); - - xColorList = XPropertyList::AsColorList(XPropertyList::CreatePropertyListFromURL( - XPropertyListType::Color, aPaletteManager.GetSelectedPalettePath())); - if (!xColorList->Load()) - continue; - - auto nPos = xColorList->GetIndexOfColor(rColor); - if (nPos == -1) - continue; - - m_xLbPaletteSelector->set_active_text(aPaletteManager.GetPaletteName()); - SelectPaletteLbHdl(*m_xLbPaletteSelector); - - m_xValSetColorBox->SelectItem(m_xValSetColorBox->GetItemId(nPos)); - - return; + aPaletteManager.SetPalette(nPalettePos, true /*bPosOnly*/); + + if (/*custom palette*/ nPalettePos == 0 || + /*theme colors palette*/ aPaletteManager.IsThemePaletteSelected() || + /*document colors palette*/ nPalettePos == aPaletteManager.GetPaletteCount() - 1) + { + aPaletteManager.ReloadColorSet(*m_xValSetColorBox); + + for (size_t nItemPos = 0, nItemCount = m_xValSetColorBox->GetItemCount(); + nItemPos < nItemCount; nItemPos++) + { + auto nItemId = m_xValSetColorBox->GetItemId(nItemPos); + if (m_xValSetColorBox->GetItemColor(nItemId) == rColor) + { + m_xLbPaletteSelector->set_active_text(aPaletteManager.GetPaletteName()); + SelectPaletteLbHdl(*m_xLbPaletteSelector); + + m_xValSetColorBox->SelectItem(nItemId); + + return; + } + } + } + else + { + xColorList = XPropertyList::AsColorList(XPropertyList::CreatePropertyListFromURL( + XPropertyListType::Color, aPaletteManager.GetSelectedPalettePath())); + if (!xColorList->Load()) + continue; + + auto nPos = xColorList->GetIndexOfColor(rColor); + if (nPos == -1) + continue; + + m_xLbPaletteSelector->set_active_text(aPaletteManager.GetPaletteName()); + SelectPaletteLbHdl(*m_xLbPaletteSelector); + + m_xValSetColorBox->SelectItem(m_xValSetColorBox->GetItemId(nPos)); + + return; + } } + + // color not found in any palette + m_xLbPaletteSelector->set_active_text(OUString()); + m_xValSetColorBox->Clear(); } SvxDefaultColorOptPage::SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) commit b677fab9172ae1c8d5a1b54419d5d171702bb62b Author: Justin Luth <[email protected]> AuthorDate: Sat Nov 29 17:08:59 2025 -0500 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Dec 16 16:48:23 2025 +0100 tdf#165180 xlsx UI: round-trip as 2007 Spreadsheet, not 2010-365 Historically we have ALWAYS round-tripped with the 2007 filter. A recent change (in this patchset) started importing xlsx without a lowestEdited as 2010+ documents, and thus they will then also export as 2010+. With this patch, we round-trip the original lowestEdited, and thus we can again round-trip 2007 as 2007. make CppunitTest_sc_subsequent_export_test2 \ CPPUNIT_TEST_NAME=testMatrixMultiplicationXLSX Change-Id: I85c4163f76902f2972193a2fdfe7ee9b4dd510c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195035 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195527 diff --git a/sc/inc/scextopt.hxx b/sc/inc/scextopt.hxx index 4a71fdd7dd30..1cc8b3f3bcd7 100644 --- a/sc/inc/scextopt.hxx +++ b/sc/inc/scextopt.hxx @@ -30,6 +30,7 @@ struct ScExtDocSettings double mfTabBarWidth; ///< Width of the tabbar, relative to frame window width (0.0 ... 1.0). sal_uInt32 mnLinkCnt; ///< Recursive counter for loading external documents. SCTAB mnDisplTab; ///< Index of displayed sheet. + std::optional<sal_Int16> moLowestEdited; ///< Oldest Excel version that edited this document. explicit ScExtDocSettings(); }; diff --git a/sc/qa/unit/subsequent_export_test2.cxx b/sc/qa/unit/subsequent_export_test2.cxx index 1e7f7a0ce920..f0cf473f2c04 100644 --- a/sc/qa/unit/subsequent_export_test2.cxx +++ b/sc/qa/unit/subsequent_export_test2.cxx @@ -127,6 +127,13 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testMatrixMultiplicationXLSX) { createScDoc("xlsx/matrix-multiplication.xlsx"); + // tdf#165180: should be recognized as a 2007 XLSX format when loaded (and resaved...) + SfxMedium* pMedium = getScDocShell()->GetMedium(); + SfxFilterMatcher aMatcher(u"com.sun.star.sheet.SpreadsheetDocument"_ustr); + std::shared_ptr<const SfxFilter> pFilter; + aMatcher.DetectFilter(*pMedium, pFilter); + CPPUNIT_ASSERT_EQUAL(u"Calc MS Excel 2007 XML"_ustr, pFilter->GetFilterName()); + save(TestFilter::XLSX); xmlDocUniquePtr pDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr); @@ -141,6 +148,11 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testMatrixMultiplicationXLSX) // make sure that the CellFormulaType is array. CPPUNIT_ASSERT_EQUAL(u"array"_ustr, CellFormulaType); + + // tdf#165180: should be recognizable as a 2007 XLSX format when saved + xmlDocUniquePtr pWorkbook = parseExport(u"xl/workbook.xml"_ustr); + // lowestEdited = 4 needs to be round-tripped in order to detect as a 2007 ECMA_376_1ST_EDITION + assertXPath(pWorkbook, "/x:workbook/x:fileVersion", "lowestEdited", u"4"); } CPPUNIT_TEST_FIXTURE(ScExportTest2, testRefStringXLSX) @@ -1418,7 +1430,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf123645XLSX) CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf125173XLSX) { createScDoc("ods/text_box_hyperlink.ods"); - save(TestFilter::XLSX); + saveAndReload(TestFilter::XLSX); xmlDocUniquePtr pDoc = parseExport(u"xl/drawings/drawing1.xml"_ustr); CPPUNIT_ASSERT(pDoc); @@ -1430,6 +1442,13 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf125173XLSX) u"http://www.google.com/"); assertXPath(pXmlRels, "/rels:Relationships/rels:Relationship[@Id='rId1']", "TargetMode", u"External"); + + // tdf#137883: should be recognized as a 2010+ XLSX format when reloaded (and resaved...) + SfxMedium* pMedium = getScDocShell()->GetMedium(); + SfxFilterMatcher aMatcher(u"com.sun.star.sheet.SpreadsheetDocument"_ustr); + std::shared_ptr<const SfxFilter> pFilter; + aMatcher.DetectFilter(*pMedium, pFilter); + CPPUNIT_ASSERT_EQUAL(u"Calc Office Open XML"_ustr, pFilter->GetFilterName()); } CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf79972XLSX) diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 0d0c6655aaab..fc794b00ab60 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -852,13 +852,17 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) FSNS(XML_xmlns, XML_xr6), rStrm.getNamespaceURL(OOX_NS(xr6)), FSNS(XML_xmlns, XML_xr10), rStrm.getNamespaceURL(OOX_NS(xr10)), FSNS(XML_xmlns, XML_xr2), rStrm.getNamespaceURL(OOX_NS(xr2)) ); - rWorkbook->singleElement( XML_fileVersion, - XML_appName, "Calc" + + rtl::Reference<sax_fastparser::FastAttributeList> pAttrListFileVersion + = sax_fastparser::FastSerializerHelper::createAttrList(); + pAttrListFileVersion->add(XML_appName, "Calc"); + std::optional<sal_Int16> oLow = GetExtDocOptions().GetDocSettings().moLowestEdited; + if (oLow.has_value()) + pAttrListFileVersion->add(XML_lowestEdited, OString::number(*oLow)); // OOXTODO: XML_codeName // OOXTODO: XML_lastEdited - // OOXTODO: XML_lowestEdited // OOXTODO: XML_rupBuild - ); + rWorkbook->singleElement(XML_fileVersion, pAttrListFileVersion); if (bHasPasswordHash) rWorkbook->singleElement(XML_fileSharing, diff --git a/sc/source/filter/inc/workbooksettings.hxx b/sc/source/filter/inc/workbooksettings.hxx index 1078b3e6c096..729daa754664 100644 --- a/sc/source/filter/inc/workbooksettings.hxx +++ b/sc/source/filter/inc/workbooksettings.hxx @@ -19,6 +19,7 @@ #pragma once +#include <scextopt.hxx> #include "workbookhelper.hxx" namespace oox { class AttributeList; } @@ -81,9 +82,12 @@ class WorkbookSettings : public WorkbookHelper { public: explicit WorkbookSettings( const WorkbookHelper& rHelper ); + ~WorkbookSettings(); /** Imports the fileSharing element containing write protection settings. */ void importFileSharing( const AttributeList& rAttribs ); + /** Imports the fileVersion element containing last-edited-by settings. */ + void importFileVersion( const AttributeList& rAttribs ); /** Imports the workbookPr element containing global workbook settings. */ void importWorkbookPr( const AttributeList& rAttribs ); /** Imports the calcPr element containing workbook calculation settings. */ @@ -112,6 +116,7 @@ private: FileSharingModel maFileSharing; WorkbookSettingsModel maBookSettings; CalcSettingsModel maCalcSettings; + ScExtDocOptions maExtDocOptions; }; } // namespace oox::xls diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 18eed29be335..14db1335349d 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -118,6 +118,7 @@ ContextHandlerRef WorkbookFragment::onCreateContext( sal_Int32 nElement, const A case XLS_TOKEN( pivotCaches ): return this; case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break; + case XLS_TOKEN( fileVersion ): getWorkbookSettings().importFileVersion( rAttribs ); break; case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break; case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break; case XLS_TOKEN( oleSize ): getViewSettings().importOleSize( rAttribs ); break; diff --git a/sc/source/filter/oox/workbooksettings.cxx b/sc/source/filter/oox/workbooksettings.cxx index 2308c644e6fa..d514d8d30b58 100644 --- a/sc/source/filter/oox/workbooksettings.cxx +++ b/sc/source/filter/oox/workbooksettings.cxx @@ -37,7 +37,9 @@ #include <oox/token/tokens.hxx> #include <unitconverter.hxx> #include <biffhelper.hxx> +#include <document.hxx> #include <docuno.hxx> +#include <scextopt.hxx> namespace oox::xls { @@ -106,6 +108,13 @@ CalcSettingsModel::CalcSettingsModel() : WorkbookSettings::WorkbookSettings( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ) { + if (getScDocument().GetExtDocOptions()) + maExtDocOptions = *getScDocument().GetExtDocOptions(); +} + +WorkbookSettings::~WorkbookSettings() +{ + getScDocument().SetExtDocOptions(std::make_unique<ScExtDocOptions>(maExtDocOptions)); } void WorkbookSettings::importFileSharing( const AttributeList& rAttribs ) @@ -119,6 +128,13 @@ void WorkbookSettings::importFileSharing( const AttributeList& rAttribs ) maFileSharing.mbRecommendReadOnly = rAttribs.getBool( XML_readOnlyRecommended, false ); } +void WorkbookSettings::importFileVersion(const AttributeList& rAttribs) +{ + const sal_Int16 nLow = rAttribs.getInteger(XML_lowestEdited, -1); + if (nLow != -1) + maExtDocOptions.GetDocSettings().moLowestEdited = nLow; +} + void WorkbookSettings::importWorkbookPr( const AttributeList& rAttribs ) { maBookSettings.maCodeName = rAttribs.getString( XML_codeName, OUString() ); commit 5e8a2f525d1eb3f1ad51a14792e50f0a63a66c08 Author: Justin Luth <[email protected]> AuthorDate: Sat Nov 29 16:06:52 2025 -0500 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Dec 16 16:48:18 2025 +0100 tdf#165180 xlsx UI: prefer Excel 2010–365 Spreadsheet, not 2007 A prior commit in this patchset clarified what "Calc Office Open XML" is targeted for. Probably it is time for us to intentionally target the 2010+ format... However, this does not yet result in the right filter being chosen for round-tripping an xlsx file... Change-Id: Ia4dc82bd55aecb24854eba66dc0c77a214d251a8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195034 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195526 diff --git a/officecfg/registry/data/org/openoffice/TypeDetection/UISort.xcu b/officecfg/registry/data/org/openoffice/TypeDetection/UISort.xcu index 7ccb01532d03..f8dc51a005d0 100644 --- a/officecfg/registry/data/org/openoffice/TypeDetection/UISort.xcu +++ b/officecfg/registry/data/org/openoffice/TypeDetection/UISort.xcu @@ -21,7 +21,7 @@ <node oor:name="ModuleDependendFilterOrder"> <node oor:name="com.sun.star.sheet.SpreadsheetDocument" oor:op="replace" install:module="calc"> <prop oor:name="SortedFilterList"> - <value oor:separator=";">calc8;calc8_template;StarOffice XML (Calc);calc_StarOffice_XML_Calc_Template;OpenDocument Spreadsheet Flat XML;UOF spreadsheet;Calc MS Excel 2007 XML;Calc MS Excel 2007 XML Template;Calc MS Excel 2007 Binary;MS Excel 2003 XML;MS Excel 97;MS Excel 97 Vorlage/Template;MS Excel 95;MS Excel 95 Vorlage/Template;MS Excel 5.0/95;MS Excel 5.0/95 Vorlage/Template;MS Excel 4.0;MS Excel 4.0 Vorlage/Template;;DIF;dBase;HTML (StarCalc);Lotus;Pocket Excel;Quattro Pro 6.0;Rich Text Format (StarCalc);SYLK;Text - txt - csv (StarCalc);calc_HTML_WebQuery;Calc Office Open XML;Calc Office Open XML Template;ADO Rowset XML</value> + <value oor:separator=";">calc8;calc8_template;StarOffice XML (Calc);calc_StarOffice_XML_Calc_Template;OpenDocument Spreadsheet Flat XML;UOF spreadsheet;Calc Office Open XML;Calc Office Open XML Template;;MS Excel 97;MS Excel 97 Vorlage/Template;MS Excel 95;MS Excel 95 Vorlage/Template;MS Excel 5.0/95;MS Excel 5.0/95 Vorlage/Template;MS Excel 4.0;MS Excel 4.0 Vorlage/Template;;DIF;dBase;HTML (StarCalc);Lotus;Pocket Excel;Quattro Pro 6.0;Rich Text Format (StarCalc);SYLK;Text - txt - csv (StarCalc);calc_HTML_WebQuery;ADO Rowset XML;Calc MS Excel 2007 XML;Calc MS Excel 2007 XML Template;Calc MS Excel 2007 Binary;Calc MS Excel 2007 VBA XML;MS Excel 2003 XML</value> </prop> </node> <node oor:name="com.sun.star.drawing.DrawingDocument" oor:op="replace" install:module="draw"> commit 7c8fa069de60572d37d3230f383716a16270e5bb Author: Justin Luth <[email protected]> AuthorDate: Fri Dec 5 20:25:47 2025 -0500 Commit: Xisco Fauli <[email protected]> CommitDate: Tue Dec 16 16:48:13 2025 +0100 tdf#165180 xlsx import: detect lowestEdited > 4 as 2010+ filter WARNING: this patch instantly flips LO to importing/exporting most xlsx documents with the Excel 2010 filter. Prior to this, everything used Excel 2007 filter for import or export. xl/workbook.xml contains a fileVersion element that has a lowestEdited value (similar to DOCX's compatibilityMode). Although undocumented, lowestEdited in practice seems to mean: - 4 is Excel 2007 - 5 is Excel 2010 - 6 is (probably) Excel 2013 - 7 is Excel 2019 (probably also 2016) My Excel 2024 produced this: <fileVersion appName="xl" lastEdited="7" lowestEdited="7" rupBuild="27928"/> If there is no lowestEdited, then just use lastEdited. There apparently is no default value for lowestEdited or lastEdited (unlike compatibilityMode - which is treated as 12 when not specified). make CppunitTest_sc_subsequent_export_test2 \ CPPUNIT_TEST_NAME=testGroupShape Change-Id: I83b093279949214cbf819d0597cb923347cfb04d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195118 Reviewed-by: Justin Luth <[email protected]> Tested-by: Jenkins Signed-off-by: Xisco Fauli <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195523 diff --git a/include/oox/core/filterdetect.hxx b/include/oox/core/filterdetect.hxx index 89b71c603f09..2ce6f030a700 100644 --- a/include/oox/core/filterdetect.hxx +++ b/include/oox/core/filterdetect.hxx @@ -77,6 +77,7 @@ public: private: void parseSettings(const AttributeList& rAttribs); + void parseWorkbook(const AttributeList& rAttribs); void parseRelationship( const AttributeList& rAttribs ); OUString getFilterNameFromContentType( std::u16string_view rContentType, std::u16string_view rFileName ); diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index b48df147673b..cc75b51ee088 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -98,6 +98,14 @@ void SAL_CALL FilterDetectDocHandler::startFastElement( parseSettings(aAttribs); break; + // cases for xl/workbook.xml + case XLS_TOKEN(workbook): + break; + case XLS_TOKEN(fileVersion): + if (!maContextStack.empty() && (maContextStack.back() == XLS_TOKEN(workbook))) + parseWorkbook(aAttribs); + break; + // cases for _rels/.rels case PR_TOKEN( Relationships ): break; @@ -164,6 +172,19 @@ void FilterDetectDocHandler::parseSettings(const AttributeList& rAttribs) } } +void FilterDetectDocHandler::parseWorkbook(const AttributeList& rAttribs) +{ + if (maOOXMLVariant != OOXMLVariant::ECMA_Transitional) + return; + + // tdf#165180 Remember filter when opening file as 'Office Open XML Spreadsheet' + // (fileVersion can only exist once, and lowestEdited can only be defined once - else corrupt) + // lowestEdited: 4 is 2007, 5 is 2010, 6 is 201?, 7 is 201?-2024 + const sal_Int32 nDefaultValue = rAttribs.getInteger(XML_lastEdited, 99); + if (rAttribs.getInteger(XML_lowestEdited, nDefaultValue) > 4) + maOOXMLVariant = OOXMLVariant::ISO_Transitional; // Excel 2010+ +} + void FilterDetectDocHandler::parseRelationship( const AttributeList& rAttribs ) { OUString aType = rAttribs.getStringDefaulted( XML_Type); @@ -230,14 +251,32 @@ OUString FilterDetectDocHandler::getFilterNameFromContentType( std::u16string_vi } if( rContentType == u"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml") - return u"MS Excel 2007 XML"_ustr; + { + switch (maOOXMLVariant) + { + case OOXMLVariant::ISO_Transitional: + case OOXMLVariant::ISO_Strict: // Not supported, map to ISO transitional + return u"Office Open XML Spreadsheet"_ustr; // Excel 2010+ + case OOXMLVariant::ECMA_Transitional: + return u"MS Excel 2007 XML"_ustr; + } + } if (rContentType == u"application/vnd.ms-excel.sheet.macroEnabled.main+xml") return u"MS Excel 2007 VBA XML"_ustr; if( rContentType == u"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" || rContentType == u"application/vnd.ms-excel.template.macroEnabled.main+xml" ) - return u"MS Excel 2007 XML Template"_ustr; + { + switch (maOOXMLVariant) + { + case OOXMLVariant::ISO_Transitional: + case OOXMLVariant::ISO_Strict: // Not supported, map to ISO transitional + return u"Office Open XML Spreadsheet Template"_ustr; // Excel 2010+ + case OOXMLVariant::ECMA_Transitional: + return u"MS Excel 2007 XML Template"_ustr; + } + } if ( rContentType == u"application/vnd.ms-excel.sheet.binary.macroEnabled.main" ) return u"MS Excel 2007 Binary"_ustr; @@ -457,6 +496,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq aParser.registerNamespace( NMSP_officeRel ); aParser.registerNamespace( NMSP_packageContentTypes ); aParser.registerNamespace(NMSP_doc); // for W_TOKEN + aParser.registerNamespace(NMSP_xls); // for XLS_TOKEN OUString aFileName; aMediaDescriptor[utl::MediaDescriptor::PROP_URL] >>= aFileName; @@ -469,11 +509,20 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq try { // Text documents can't use .rels to determine maOOXMLVariant. Use compatibilityMode - aParser.parseStream(aZipStorage, u"word/settings.xml"_ustr); + aParser.parseStream(aZipStorage, u"word/settings.xml"_ustr); } catch(const Exception&) { // not a MS Word text document, or file might not exist + try + { + // Spreadsheets distinguish maOOXMLVariant using fileVersion lowestEdited + aParser.parseStream(aZipStorage, u"xl/workbook.xml"_ustr); + } + catch(const Exception&) + { + // not a MS Excel spreadsheet document, or file might not exist + } } // Order is critical: .rels and then settings.xml must be parsed before [Content_Types] aParser.parseStream( aZipStorage, u"[Content_Types].xml"_ustr ); diff --git a/sc/qa/unit/subsequent_export_test2.cxx b/sc/qa/unit/subsequent_export_test2.cxx index eec405eaa66d..1e7f7a0ce920 100644 --- a/sc/qa/unit/subsequent_export_test2.cxx +++ b/sc/qa/unit/subsequent_export_test2.cxx @@ -21,6 +21,8 @@ #include <comphelper/propertyvalue.hxx> #include <unotools/syslocaleoptions.hxx> #include <formula/grammar.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/fcontnr.hxx> #include <svl/numformat.hxx> #include <svl/zformat.hxx> #include <svx/svdograf.hxx> @@ -45,8 +47,15 @@ ScExportTest2::ScExportTest2() CPPUNIT_TEST_FIXTURE(ScExportTest2, testGroupShape) { createScDoc("xlsx/groupShape.xlsx"); - save(TestFilter::XLSX); + // tdf#165180: should be recognized as a 2010+ XLSX format when loaded (and resaved...) + SfxMedium* pMedium = getScDocShell()->GetMedium(); + SfxFilterMatcher aMatcher(u"com.sun.star.sheet.SpreadsheetDocument"_ustr); + std::shared_ptr<const SfxFilter> pFilter; + aMatcher.DetectFilter(*pMedium, pFilter); + CPPUNIT_ASSERT_EQUAL_MESSAGE("import", u"Calc Office Open XML"_ustr, pFilter->GetFilterName()); + + save(TestFilter::XLSX); xmlDocUniquePtr pDoc = parseExport(u"xl/drawings/drawing1.xml"_ustr); CPPUNIT_ASSERT(pDoc); assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:grpSp/xdr:grpSpPr");
