summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2022-04-13 08:40:23 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2022-04-13 15:46:59 +0200
commit064f4fe82c30118a34c4aeb47bf8604f0b8356a1 (patch)
tree281c28c1b10e6b39c0a330c64928c933818cb77f /filter
parent15f70da655301be4d66abf91ee788b50e8ab1215 (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.mk1
-rw-r--r--filter/qa/unit/data/calc.otsbin0 -> 9564 bytes
-rw-r--r--filter/qa/unit/data/impress.otpbin0 -> 15382 bytes
-rw-r--r--filter/qa/unit/data/writer.ottbin0 -> 10017 bytes
-rw-r--r--filter/qa/unit/textfilterdetect.cxx159
-rw-r--r--filter/source/textfilterdetect/filterdetect.cxx53
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
new file mode 100644
index 000000000000..d16d2307fee9
--- /dev/null
+++ b/filter/qa/unit/data/calc.ots
Binary files differ
diff --git a/filter/qa/unit/data/impress.otp b/filter/qa/unit/data/impress.otp
new file mode 100644
index 000000000000..199a5f9d470f
--- /dev/null
+++ b/filter/qa/unit/data/impress.otp
Binary files differ
diff --git a/filter/qa/unit/data/writer.ott b/filter/qa/unit/data/writer.ott
new file mode 100644
index 000000000000..1ded03150e01
--- /dev/null
+++ b/filter/qa/unit/data/writer.ott
Binary files differ
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);
}