diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2022-04-13 08:40:23 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2022-04-13 15:46:59 +0200 |
commit | 064f4fe82c30118a34c4aeb47bf8604f0b8356a1 (patch) | |
tree | 281c28c1b10e6b39c0a330c64928c933818cb77f /filter | |
parent | 15f70da655301be4d66abf91ee788b50e8ab1215 (diff) |
tdf#139991: move 0-byte file handling to SfxFrameLoader_Impl::load
This centralizes the code that handles templates, and allows the empty
files to use default templates.
This partially reverts commits:
ada07f303e7cd1e39c73abe0741aefe7d9d73a57
Author Miklos Vajna <vmiklos@collabora.com>
Date Wed Oct 28 14:54:52 2020 +0100
tdf#123476 filter: try to detect 0-byte files based on extension
2854362f429e476d4a1ab4759c6a1f1c04150280
Author Mike Kaganski <mike.kaganski@collabora.com>
Date Wed Jan 27 16:05:54 2021 +0100
tdf#123476 filter: Also handle empty ODF
dff586735b6618d9b011823594a33287d8f7f223
Author Mike Kaganski <mike.kaganski@collabora.com>
Date Mon May 03 17:04:04 2021 +0200
tdf#123476: also use filter by extension when its service is the same
The unit tests from these commits are retained and extended for templates.
Change-Id: I755738d2d5a6d6955d84d6e12f3accc017e0391f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132938
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'filter')
-rw-r--r-- | filter/CppunitTest_filter_textfilterdetect.mk | 1 | ||||
-rw-r--r-- | filter/qa/unit/data/calc.ots | bin | 0 -> 9564 bytes | |||
-rw-r--r-- | filter/qa/unit/data/impress.otp | bin | 0 -> 15382 bytes | |||
-rw-r--r-- | filter/qa/unit/data/writer.ott | bin | 0 -> 10017 bytes | |||
-rw-r--r-- | filter/qa/unit/textfilterdetect.cxx | 159 | ||||
-rw-r--r-- | filter/source/textfilterdetect/filterdetect.cxx | 53 |
6 files changed, 107 insertions, 106 deletions
diff --git a/filter/CppunitTest_filter_textfilterdetect.mk b/filter/CppunitTest_filter_textfilterdetect.mk index 4066c26591a3..6fb22f8b074e 100644 --- a/filter/CppunitTest_filter_textfilterdetect.mk +++ b/filter/CppunitTest_filter_textfilterdetect.mk @@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,filter_textfilterdetect, \ cppu \ cppuhelper \ sal \ + sfx \ test \ textfd \ tl \ diff --git a/filter/qa/unit/data/calc.ots b/filter/qa/unit/data/calc.ots Binary files differnew file mode 100644 index 000000000000..d16d2307fee9 --- /dev/null +++ b/filter/qa/unit/data/calc.ots diff --git a/filter/qa/unit/data/impress.otp b/filter/qa/unit/data/impress.otp Binary files differnew file mode 100644 index 000000000000..199a5f9d470f --- /dev/null +++ b/filter/qa/unit/data/impress.otp diff --git a/filter/qa/unit/data/writer.ott b/filter/qa/unit/data/writer.ott Binary files differnew file mode 100644 index 000000000000..1ded03150e01 --- /dev/null +++ b/filter/qa/unit/data/writer.ott diff --git a/filter/qa/unit/textfilterdetect.cxx b/filter/qa/unit/textfilterdetect.cxx index bbb9b91b527f..3c8daf2f2ef9 100644 --- a/filter/qa/unit/textfilterdetect.cxx +++ b/filter/qa/unit/textfilterdetect.cxx @@ -13,8 +13,13 @@ #include <com/sun/star/document/XExtendedFilterDetection.hpp> #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/sheet/XCellRangesAccess.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/text/XTextDocument.hpp> #include <comphelper/propertyvalue.hxx> +#include <sfx2/docfac.hxx> #include <unotools/mediadescriptor.hxx> #include <unotools/streamwrap.hxx> #include <tools/stream.hxx> @@ -31,12 +36,8 @@ namespace /// Test class for PlainTextFilterDetect. class TextFilterDetectTest : public test::BootstrapFixture, public unotest::MacrosTest { - uno::Reference<lang::XComponent> mxComponent; - public: void setUp() override; - void tearDown() override; - uno::Reference<lang::XComponent>& getComponent() { return mxComponent; } }; void TextFilterDetectTest::setUp() @@ -46,14 +47,6 @@ void TextFilterDetectTest::setUp() mxDesktop.set(frame::Desktop::create(mxComponentContext)); } -void TextFilterDetectTest::tearDown() -{ - if (mxComponent.is()) - mxComponent->dispose(); - - test::BootstrapFixture::tearDown(); -} - constexpr OUStringLiteral DATA_DIRECTORY = u"/filter/qa/unit/data/"; CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428) @@ -78,68 +71,126 @@ CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428) CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testEmptyFile) { - // Given an empty file, with a pptx extension - OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.pptx"; + const OUString sDataDirectory = m_directories.getURLFromSrc(DATA_DIRECTORY); + auto supportsService = [](const uno::Reference<lang::XComponent>& x, const OUString& s) { + return uno::Reference<lang::XServiceInfo>(x, uno::UNO_QUERY_THROW)->supportsService(s); + }; + // Given an empty file, with a pptx extension // When loading the file - getComponent() = loadFromDesktop(aURL); + auto xComponent = loadFromDesktop(sDataDirectory + "empty.pptx"); // Then make sure it is opened in Impress. - uno::Reference<lang::XServiceInfo> xServiceInfo(getComponent(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xServiceInfo.is()); - // Without the accompanying fix in place, this test would have failed, as it was opened in // Writer instead. - CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument")); - - getComponent()->dispose(); + CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.presentation.PresentationDocument")); + xComponent->dispose(); // Now also test ODT - aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.odt"; - getComponent() = loadFromDesktop(aURL); - xServiceInfo.set(getComponent(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xServiceInfo.is()); + xComponent = loadFromDesktop(sDataDirectory + "empty.odt"); // Make sure it opens in Writer. - CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextDocument")); - getComponent()->dispose(); + CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.text.TextDocument")); + xComponent->dispose(); // ... and ODS - aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.ods"; - getComponent() = loadFromDesktop(aURL); - xServiceInfo.set(getComponent(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xServiceInfo.is()); + xComponent = loadFromDesktop(sDataDirectory + "empty.ods"); // Make sure it opens in Calc. - CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument")); - getComponent()->dispose(); + CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.sheet.SpreadsheetDocument")); + xComponent->dispose(); // ... and ODP - aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.odp"; - getComponent() = loadFromDesktop(aURL); - xServiceInfo.set(getComponent(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xServiceInfo.is()); + xComponent = loadFromDesktop(sDataDirectory + "empty.odp"); // Without the accompanying fix in place, this test would have failed, as it was opened in // Writer instead. - CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument")); - getComponent()->dispose(); + CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.presentation.PresentationDocument")); + xComponent->dispose(); // ... and DOC - aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.doc"; // Without the accompanying fix in place, this test would have failed, the import filter aborted // loading. - getComponent() = loadFromDesktop(aURL); - xServiceInfo.set(getComponent(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xServiceInfo.is()); - CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextDocument")); - uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aArgs = xModel->getArgs(); - comphelper::SequenceAsHashMap aMap(aArgs); - OUString aFilterName; - aMap["FilterName"] >>= aFilterName; - // Without the accompanying fix in place, this test would have failed with: - // - Expected: MS Word 97 - // - Actual : MS WinWord 6.0 - // i.e. opening worked, but saving back failed instead of producing a WW8 binary file. - CPPUNIT_ASSERT_EQUAL(OUString("MS Word 97"), aFilterName); + xComponent = loadFromDesktop(sDataDirectory + "empty.doc"); + CPPUNIT_ASSERT(supportsService(xComponent, "com.sun.star.text.TextDocument")); + { + uno::Reference<frame::XModel> xModel(xComponent, uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aArgs = xModel->getArgs(); + comphelper::SequenceAsHashMap aMap(aArgs); + OUString aFilterName; + aMap["FilterName"] >>= aFilterName; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: MS Word 97 + // - Actual : MS WinWord 6.0 + // i.e. opening worked, but saving back failed instead of producing a WW8 binary file. + CPPUNIT_ASSERT_EQUAL(OUString("MS Word 97"), aFilterName); + } + xComponent->dispose(); + + // Now test with default templates set + + SfxObjectFactory::SetStandardTemplate("com.sun.star.presentation.PresentationDocument", + sDataDirectory + "impress.otp"); + SfxObjectFactory::SetStandardTemplate("com.sun.star.text.TextDocument", + sDataDirectory + "writer.ott"); + SfxObjectFactory::SetStandardTemplate("com.sun.star.sheet.SpreadsheetDocument", + sDataDirectory + "calc.ots"); + + xComponent = loadFromDesktop(sDataDirectory + "empty.pptx"); + { + uno::Reference<drawing::XDrawPagesSupplier> xDoc(xComponent, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPages> xPages(xDoc->getDrawPages(), uno::UNO_SET_THROW); + uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference<text::XTextRange> xBox(xPage->getByIndex(0), uno::UNO_QUERY_THROW); + + // Make sure the template's text was loaded + CPPUNIT_ASSERT_EQUAL(OUString("Title of Impress template"), xBox->getString()); + } + xComponent->dispose(); + + xComponent = loadFromDesktop(sDataDirectory + "empty.odt"); + { + uno::Reference<text::XTextDocument> xDoc(xComponent, uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumerationAccess> xEA(xDoc->getText(), uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumeration> xEnum(xEA->createEnumeration(), uno::UNO_SET_THROW); + uno::Reference<text::XTextRange> xParagraph(xEnum->nextElement(), uno::UNO_QUERY_THROW); + + // Make sure the template's text was loaded + CPPUNIT_ASSERT_EQUAL(OUString(u"Writer template’s first line"), xParagraph->getString()); + } + xComponent->dispose(); + + xComponent = loadFromDesktop(sDataDirectory + "empty.ods"); + { + uno::Reference<sheet::XSpreadsheetDocument> xDoc(xComponent, uno::UNO_QUERY_THROW); + uno::Reference<sheet::XCellRangesAccess> xRA(xDoc->getSheets(), uno::UNO_QUERY_THROW); + uno::Reference<text::XTextRange> xC(xRA->getCellByPosition(0, 0, 0), uno::UNO_QUERY_THROW); + + // Make sure the template's text was loaded + CPPUNIT_ASSERT_EQUAL(OUString(u"Calc template’s first cell"), xC->getString()); + } + xComponent->dispose(); + + xComponent = loadFromDesktop(sDataDirectory + "empty.odp"); + { + uno::Reference<drawing::XDrawPagesSupplier> xDoc(xComponent, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPages> xPages(xDoc->getDrawPages(), uno::UNO_SET_THROW); + uno::Reference<drawing::XDrawPage> xPage(xPages->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference<text::XTextRange> xBox(xPage->getByIndex(0), uno::UNO_QUERY_THROW); + + // Make sure the template's text was loaded + CPPUNIT_ASSERT_EQUAL(OUString("Title of Impress template"), xBox->getString()); + } + xComponent->dispose(); + + xComponent = loadFromDesktop(sDataDirectory + "empty.doc"); + { + uno::Reference<text::XTextDocument> xDoc(xComponent, uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumerationAccess> xEA(xDoc->getText(), uno::UNO_QUERY_THROW); + uno::Reference<container::XEnumeration> xEnum(xEA->createEnumeration(), uno::UNO_SET_THROW); + uno::Reference<text::XTextRange> xParagraph(xEnum->nextElement(), uno::UNO_QUERY_THROW); + + // Make sure the template's text was loaded + CPPUNIT_ASSERT_EQUAL(OUString(u"Writer template’s first line"), xParagraph->getString()); + } + xComponent->dispose(); } } diff --git a/filter/source/textfilterdetect/filterdetect.cxx b/filter/source/textfilterdetect/filterdetect.cxx index 0edbb1f4cc47..9d25e289ec89 100644 --- a/filter/source/textfilterdetect/filterdetect.cxx +++ b/filter/source/textfilterdetect/filterdetect.cxx @@ -20,8 +20,6 @@ #include <com/sun/star/io/XInputStream.hpp> #include <cppuhelper/supportsservice.hxx> #include <memory> -#include <sfx2/fcontnr.hxx> -#include <sfx2/docfilt.hxx> constexpr OUStringLiteral WRITER_TEXT_FILTER = u"Text"; constexpr OUStringLiteral CALC_TEXT_FILTER = u"Text - txt - csv (StarCalc)"; @@ -129,45 +127,6 @@ bool IsHTMLStream( const uno::Reference<io::XInputStream>& xInStream ) OString aToken = sHeader.copy( nStartOfTagIndex, i - nStartOfTagIndex ); return GetHTMLToken( OStringToOUString( aToken.toAsciiLowerCase(), RTL_TEXTENCODING_ASCII_US ) ) != HtmlTokenId::NONE; } - -/** - * Given an (empty) file URL in rMediaDesc and rExt, looks up the best filter type for it and - * writes the type name to rType, the filter name to rMediaDesc. - */ -bool HandleEmptyFileUrlByExtension(MediaDescriptor& rMediaDesc, const OUString& rExt, - OUString& rType, OUString& rService) -{ - OUString aURL = rMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL, OUString()); - if (!tools::isEmptyFileUrl(aURL)) - { - return false; - } - - if (rExt.isEmpty()) - { - return false; - } - - // Requiring the export+preferred flags helps to find the relevant filter, e.g. .doc -> WW8 (and - // not WW6 or Mac_Word). - SfxFilterFlags nMust - = SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::PREFERED; - std::shared_ptr<const SfxFilter> pFilter(SfxFilterMatcher().GetFilter4Extension(rExt, nMust)); - if (!pFilter) - { - // retry without PREFERRED so we can find at least something for 0-byte *.ods - nMust = SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT; - pFilter = SfxFilterMatcher().GetFilter4Extension(rExt, nMust); - - if (!pFilter) - return false; - } - - rMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= pFilter->GetFilterName(); - rType = pFilter->GetTypeName(); - rService = pFilter->GetServiceName(); - return true; -} } PlainTextFilterDetect::PlainTextFilterDetect() {} @@ -226,15 +185,7 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal OUString aName = aParser.getName().toAsciiLowerCase(); // Decide which filter to use based on the document service first, - // then on extension if that's not available. Make exception for 0-byte files - // whose extensions are handled by the same service as passed document service. - OUString aEmptyType, aEmptyService; - bool bEmpty = HandleEmptyFileUrlByExtension(aMediaDesc, aExt, aEmptyType, aEmptyService); - if (bEmpty && aDocService == aEmptyService) - { - aDocService.clear(); // don't fallback to text filter, use extension-based match - // TODO: maybe reset aExt when it's "xls" - } + // then on extension if that's not available. if (aDocService == CALC_DOCSERVICE) aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(CALC_TEXT_FILTER); @@ -242,8 +193,6 @@ OUString SAL_CALL PlainTextFilterDetect::detect(uno::Sequence<beans::PropertyVal aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(WRITER_TEXT_FILTER); else if (aExt == "csv" || aExt == "tsv" || aExt == "tab" || aExt == "xls" || aName.endsWith(".csv.gz")) aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(CALC_TEXT_FILTER); - else if (bEmpty) - aType = aEmptyType; // aMediaDesc is already updated in HandleEmptyFileUrlByExtension else aMediaDesc[MediaDescriptor::PROP_FILTERNAME] <<= OUString(WRITER_TEXT_FILTER); } |