summaryrefslogtreecommitdiffstats
path: root/filter/qa/unit
diff options
context:
space:
mode:
Diffstat (limited to 'filter/qa/unit')
-rw-r--r--filter/qa/unit/data/attributeRedefinedTest.odpbin0 -> 12610 bytes
-rw-r--r--filter/qa/unit/data/calc.otsbin0 -> 9564 bytes
-rw-r--r--filter/qa/unit/data/empty.ods0
-rw-r--r--filter/qa/unit/data/hybrid_calc.pdfbin0 -> 10420 bytes
-rw-r--r--filter/qa/unit/data/hybrid_impress.pdfbin0 -> 21055 bytes
-rw-r--r--filter/qa/unit/data/hybrid_writer.pdfbin0 -> 10732 bytes
-rw-r--r--filter/qa/unit/data/impress.otpbin0 -> 15382 bytes
-rw-r--r--filter/qa/unit/data/semi-transparent-fill.odgbin0 -> 10597 bytes
-rw-r--r--filter/qa/unit/data/text-in-image.odpbin0 -> 13584 bytes
-rw-r--r--filter/qa/unit/data/writer.ottbin0 -> 10017 bytes
-rw-r--r--filter/qa/unit/svg.cxx277
-rw-r--r--filter/qa/unit/textfilterdetect.cxx227
12 files changed, 354 insertions, 150 deletions
diff --git a/filter/qa/unit/data/attributeRedefinedTest.odp b/filter/qa/unit/data/attributeRedefinedTest.odp
new file mode 100644
index 000000000000..dfb814bfb9ec
--- /dev/null
+++ b/filter/qa/unit/data/attributeRedefinedTest.odp
Binary files differ
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/empty.ods b/filter/qa/unit/data/empty.ods
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/filter/qa/unit/data/empty.ods
diff --git a/filter/qa/unit/data/hybrid_calc.pdf b/filter/qa/unit/data/hybrid_calc.pdf
new file mode 100644
index 000000000000..b104113a5238
--- /dev/null
+++ b/filter/qa/unit/data/hybrid_calc.pdf
Binary files differ
diff --git a/filter/qa/unit/data/hybrid_impress.pdf b/filter/qa/unit/data/hybrid_impress.pdf
new file mode 100644
index 000000000000..78e7136211f4
--- /dev/null
+++ b/filter/qa/unit/data/hybrid_impress.pdf
Binary files differ
diff --git a/filter/qa/unit/data/hybrid_writer.pdf b/filter/qa/unit/data/hybrid_writer.pdf
new file mode 100644
index 000000000000..00cf3de44c5c
--- /dev/null
+++ b/filter/qa/unit/data/hybrid_writer.pdf
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/semi-transparent-fill.odg b/filter/qa/unit/data/semi-transparent-fill.odg
new file mode 100644
index 000000000000..713f48991bcb
--- /dev/null
+++ b/filter/qa/unit/data/semi-transparent-fill.odg
Binary files differ
diff --git a/filter/qa/unit/data/text-in-image.odp b/filter/qa/unit/data/text-in-image.odp
new file mode 100644
index 000000000000..660e27062373
--- /dev/null
+++ b/filter/qa/unit/data/text-in-image.odp
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/svg.cxx b/filter/qa/unit/svg.cxx
index 3e3508fd52ca..82dc3832e1b8 100644
--- a/filter/qa/unit/svg.cxx
+++ b/filter/qa/unit/svg.cxx
@@ -9,56 +9,34 @@
#include <sal/config.h>
-#include <string_view>
+#include <test/unoapixml_test.hxx>
-#include <test/bootstrapfixture.hxx>
-#include <unotest/macros_test.hxx>
-#include <test/xmltesttools.hxx>
-
-#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <comphelper/propertyvalue.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/mediadescriptor.hxx>
#include <tools/stream.hxx>
using namespace ::com::sun::star;
-constexpr OUStringLiteral DATA_DIRECTORY = u"/filter/qa/unit/data/";
-
/// SVG filter tests.
-class SvgFilterTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
+class SvgFilterTest : public UnoApiXmlTest
{
-private:
- uno::Reference<lang::XComponent> mxComponent;
-
public:
- void setUp() override;
- void tearDown() override;
+ SvgFilterTest();
void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override;
- uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
- void load(std::u16string_view rURL);
};
-void SvgFilterTest::setUp()
+SvgFilterTest::SvgFilterTest()
+ : UnoApiXmlTest("/filter/qa/unit/data/")
{
- test::BootstrapFixture::setUp();
-
- mxDesktop.set(frame::Desktop::create(mxComponentContext));
-}
-
-void SvgFilterTest::tearDown()
-{
- if (mxComponent.is())
- mxComponent->dispose();
-
- test::BootstrapFixture::tearDown();
-}
-
-void SvgFilterTest::load(std::u16string_view rFileName)
-{
- OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + rFileName;
- mxComponent = loadFromDesktop(aURL);
}
void SvgFilterTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
@@ -68,27 +46,23 @@ void SvgFilterTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testPreserveJpg)
{
-#if !defined(MACOSX)
+// On Windows, SVGFilter::filterWriterOrCalc can't get current frame to obtain selection
+#if !defined(MACOSX) && !defined(_WIN32)
// Load a document with a jpeg image in it.
- load(u"preserve-jpg.odt");
+ loadFromFile(u"preserve-jpg.odt");
// Select the image.
- dispatchCommand(getComponent(), ".uno:JumpToNextFrame", {});
+ dispatchCommand(mxComponent, ".uno:JumpToNextFrame", {});
// Export the selection to SVG.
- uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
- SvMemoryStream aStream;
- uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
- utl::MediaDescriptor aMediaDescriptor;
- aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
- aMediaDescriptor["SelectionOnly"] <<= true;
- aMediaDescriptor["OutputStream"] <<= xOut;
- xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
- aStream.Seek(STREAM_SEEK_TO_BEGIN);
+ saveWithParams({
+ comphelper::makePropertyValue("FilterName", u"writer_svg_Export"_ustr),
+ comphelper::makePropertyValue("SelectionOnly", true),
+ });
// Make sure that the original JPG data is reused and we don't perform a PNG re-compress.
- xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
- OUString aAttributeValue = getXPath(pXmlDoc, "//svg:image", "href");
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+ OUString aAttributeValue = getXPath(pXmlDoc, "//svg:image"_ostr, "href"_ostr);
// Without the accompanying fix in place, this test would have failed with:
// - Expression: aAttributeValue.startsWith("data:image/jpeg")
@@ -101,22 +75,15 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testPreserveJpg)
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentLine)
{
// Load a document with a semi-transparent line shape.
- load(u"semi-transparent-line.odg");
+ loadFromFile(u"semi-transparent-line.odg");
// Export it to SVG.
- uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
- SvMemoryStream aStream;
- uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
- utl::MediaDescriptor aMediaDescriptor;
- aMediaDescriptor["FilterName"] <<= OUString("draw_svg_Export");
- aMediaDescriptor["OutputStream"] <<= xOut;
- xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
- aStream.Seek(STREAM_SEEK_TO_BEGIN);
+ save("draw_svg_Export");
// Get the style of the group around the actual <path> element.
- xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
OUString aStyle = getXPath(
- pXmlDoc, "//svg:g[@class='com.sun.star.drawing.LineShape']/svg:g/svg:g", "style");
+ pXmlDoc, "//svg:g[@class='com.sun.star.drawing.LineShape']/svg:g/svg:g"_ostr, "style"_ostr);
// Without the accompanying fix in place, this test would have failed, as the style was
// "mask:url(#mask1)", not "opacity: <value>".
CPPUNIT_ASSERT(aStyle.startsWith("opacity: ", &aStyle));
@@ -125,6 +92,33 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentLine)
CPPUNIT_ASSERT_EQUAL(30, nPercent);
}
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentFillWithTransparentLine)
+{
+ // Load a document with a shape with semi-transparent fill and line
+ loadFromFile(u"semi-transparent-fill.odg");
+
+ // Export it to SVG.
+ save("draw_svg_Export");
+
+ // Get the style of the group around the actual <path> element.
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+ OUString aStyle
+ = getXPath(pXmlDoc, "//svg:g[@class='com.sun.star.drawing.EllipseShape']/svg:g/svg:g"_ostr,
+ "style"_ostr);
+ CPPUNIT_ASSERT(aStyle.startsWith("opacity: ", &aStyle));
+ int nPercent = std::round(aStyle.toDouble() * 100);
+ // Make sure that the line is still 50% opaque
+ CPPUNIT_ASSERT_EQUAL(50, nPercent);
+
+ // Get the stroke of the fill of the EllipseShape (it must be "none")
+ OUString aStroke = getXPath(
+ pXmlDoc, "//svg:g[@class='com.sun.star.drawing.EllipseShape']/svg:g/svg:path"_ostr,
+ "stroke"_ostr);
+ // Without the accompanying fix in place, this test would have failed, as the stroke was
+ // "rgb(255,255,255)", not "none".
+ CPPUNIT_ASSERT_EQUAL(OUString("none"), aStroke);
+}
+
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentText)
{
// Two shapes, one with transparent text and the other one with
@@ -132,21 +126,12 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentText)
// correct transparency factor applied for the first shape.
// Load draw document with transparent text in one box
- load(u"TransparentText.odg");
+ loadFromFile(u"TransparentText.odg");
// Export to SVG.
- uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
-
- SvMemoryStream aStream;
- uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
- utl::MediaDescriptor aMediaDescriptor;
- aMediaDescriptor["FilterName"] <<= OUString("draw_svg_Export");
- aMediaDescriptor["OutputStream"] <<= xOut;
- xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
- aStream.Seek(STREAM_SEEK_TO_BEGIN);
-
- xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+ save("draw_svg_Export");
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
// We expect 2 groups of class "TextShape" that
// have some svg:text node inside.
// Without the accompanying fix in place, this test would have failed with:
@@ -154,22 +139,66 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentText)
// - Actual : 1
// i.e. the 2nd shape lots its text.
- assertXPath(pXmlDoc, "//svg:g[@class='TextShape']//svg:text", 2);
+ assertXPath(pXmlDoc, "//svg:g[@class='TextShape']//svg:text"_ostr, 2);
// First shape has semi-transparent text.
- assertXPath(pXmlDoc, "//svg:text[1]/svg:tspan/svg:tspan/svg:tspan[@fill-opacity='0.8']");
+ assertXPath(pXmlDoc, "//svg:text[1]/svg:tspan/svg:tspan/svg:tspan[@fill-opacity='0.8']"_ostr);
// Second shape has normal text.
- assertXPath(pXmlDoc, "//svg:text[2]/svg:tspan/svg:tspan/svg:tspan[@fill-opacity]", 0);
+ assertXPath(pXmlDoc, "//svg:text[2]/svg:tspan/svg:tspan/svg:tspan[@fill-opacity]"_ostr, 0);
+}
+
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, testSemiTransparentMultiParaText)
+{
+ // Given a shape with semi-transparent, multi-paragraph text:
+ mxComponent
+ = loadFromDesktop("private:factory/simpress", "com.sun.star.drawing.DrawingDocument");
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XShapes> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ xDrawPage->add(xShape);
+ xShape->setSize(awt::Size(10000, 10000));
+ uno::Reference<text::XSimpleText> xShapeText(xShape, uno::UNO_QUERY);
+ uno::Reference<text::XTextCursor> xCursor = xShapeText->createTextCursor();
+ xShapeText->insertString(xCursor, "foo", /*bAbsorb=*/false);
+ xShapeText->insertControlCharacter(xCursor, text::ControlCharacter::APPEND_PARAGRAPH,
+ /*bAbsorb=*/false);
+ xShapeText->insertString(xCursor, "bar", /*bAbsorb=*/false);
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+ xShapeProps->setPropertyValue("CharColor", uno::Any(static_cast<sal_Int32>(0xff0000)));
+ xShapeProps->setPropertyValue("CharTransparence", uno::Any(static_cast<sal_Int16>(20)));
+
+ // When exporting to SVG:
+ save("draw_svg_Export");
+
+ // Then make sure that the two semi-transparent paragraphs have the same X position:
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+ assertXPath(pXmlDoc, "(//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition'])[1]"_ostr,
+ "x"_ostr, "250");
+ assertXPath(pXmlDoc,
+ "(//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition'])[1]/svg:tspan"_ostr,
+ "fill-opacity"_ostr, "0.8");
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 250
+ // - Actual : 8819
+ // i.e. the X position of the second paragraph was wrong.
+ assertXPath(pXmlDoc, "(//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition'])[2]"_ostr,
+ "x"_ostr, "250");
+ assertXPath(pXmlDoc,
+ "(//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition'])[2]/svg:tspan"_ostr,
+ "fill-opacity"_ostr, "0.8");
}
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testShapeNographic)
{
// Load a document containing a 3D shape.
- load(u"shape-nographic.odp");
+ loadFromFile(u"shape-nographic.odp");
// Export to SVG.
- uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY_THROW);
SvMemoryStream aStream;
uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
utl::MediaDescriptor aMediaDescriptor;
@@ -185,20 +214,13 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testShapeNographic)
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testCustomBullet)
{
// Given a presentation with a custom bullet:
- load(u"custom-bullet.fodp");
+ loadFromFile(u"custom-bullet.fodp");
// When exporting that to SVG:
- uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
- SvMemoryStream aStream;
- uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
- utl::MediaDescriptor aMediaDescriptor;
- aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
- aMediaDescriptor["OutputStream"] <<= xOut;
- xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
+ save("impress_svg_Export");
// Then make sure the bullet glyph is not lost:
- aStream.Seek(STREAM_SEEK_TO_BEGIN);
- xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 1
// - Actual : 0
@@ -206,7 +228,88 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testCustomBullet)
// i.e. the custom bullet used '<use transform="scale(285,285)"
// xlink:href="#bullet-char-template-45"/>', but nobody produced a bullet-char-template-45,
// instead we need the path of the glyph inline.
- CPPUNIT_ASSERT(!getXPath(pXmlDoc, "//svg:g[@class='BulletChars']//svg:path", "d").isEmpty());
+ CPPUNIT_ASSERT(
+ !getXPath(pXmlDoc, "//svg:g[@class='BulletChars']//svg:path"_ostr, "d"_ostr).isEmpty());
+}
+
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, attributeRedefinedTest)
+{
+ // Load document containing empty paragraphs with ids.
+ loadFromFile(u"attributeRedefinedTest.odp");
+
+ // Export to SVG.
+ save("impress_svg_Export");
+
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+ // We expect four paragraph
+ // 2 empty paragraphs with ids
+ // 2 paragraphs with text
+ // Without the accompanying fix the test would have failed with
+ // Expected : 4
+ // Actual : 2
+ // i.e. 2 of the empty paragraph do not get generated even if there
+ // is id imported for the paragraphs
+ // If we don't create the empty paragraphs the id attribute gets redefined like this:
+ // <tspan id="id14" id="id15" id="id17" class="TextParagraph" font-family="Bahnschrift Light" font-size="1129px" font-weight="400">
+
+ OString xPath = "//svg:g[@class='TextShape']//svg:text[@class='SVGTextShape']//"
+ "svg:tspan[@class='TextParagraph']"_ostr;
+ assertXPath(pXmlDoc, xPath, 4);
+
+ //assert that each tspan element with TextParagraph class has id and the tspan element of
+ //each empty paragraph does not contain tspan element with class TextPosition
+ assertXPath(pXmlDoc, xPath + "[1]", "id"_ostr, "id4");
+ assertXPath(pXmlDoc, xPath + "[2]", "id"_ostr, "id5");
+ assertXPath(pXmlDoc, xPath + "[2]//svg:tspan[@class='TextPosition']", 0);
+ assertXPath(pXmlDoc, xPath + "[3]", "id"_ostr, "id6");
+ assertXPath(pXmlDoc, xPath + "[3]//svg:tspan[@class='TextPosition']", 0);
+ assertXPath(pXmlDoc, xPath + "[4]", "id"_ostr, "id7");
+}
+
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, testTab)
+{
+ // Given a shape with "A\tB" text:
+ mxComponent = loadFromDesktop("private:factory/simpress",
+ "com.sun.star.presentation.PresentationDocument");
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XShapes> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ xDrawPage->add(xShape);
+ xShape->setSize(awt::Size(10000, 10000));
+ uno::Reference<text::XTextRange> xShapeText(xShape, uno::UNO_QUERY);
+ xShapeText->setString("A\tB");
+
+ // When exporting that document to SVG:
+ save("impress_svg_Export");
+
+ // Then make sure the tab is not lost:
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // i.e. the 2nd text portion was not positioned, which looked as if the tab is lost.
+ assertXPath(pXmlDoc, "//svg:g[@class='TextShape']//svg:tspan[@class='TextPosition']"_ostr, 2);
+}
+
+CPPUNIT_TEST_FIXTURE(SvgFilterTest, textInImage)
+{
+ // Load document containing empty paragraphs with ids.
+ loadFromFile(u"text-in-image.odp");
+
+ // Export to SVG.
+ save("impress_svg_Export");
+
+ xmlDocUniquePtr pXmlDoc = parseExportedFile();
+
+ // We expect the Graphic to have an image and a text
+ assertXPath(pXmlDoc, "//svg:g[@class='Graphic']//svg:image"_ostr, 1);
+ assertXPath(pXmlDoc, "//svg:g[@class='Graphic']//svg:text"_ostr, 1);
+ // Without the accompanying fix, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/filter/qa/unit/textfilterdetect.cxx b/filter/qa/unit/textfilterdetect.cxx
index 62d0d60a23a7..e578d4b88fee 100644
--- a/filter/qa/unit/textfilterdetect.cxx
+++ b/filter/qa/unit/textfilterdetect.cxx
@@ -7,14 +7,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include <test/bootstrapfixture.hxx>
-#include <unotest/macros_test.hxx>
+#include <test/unoapi_test.hxx>
#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/configuration.hxx>
#include <comphelper/propertyvalue.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <sfx2/docfac.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotools/streamwrap.hxx>
#include <tools/stream.hxx>
@@ -28,40 +34,27 @@ using namespace com::sun::star;
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()
+bool supportsService(const uno::Reference<lang::XComponent>& x, const OUString& s)
{
- test::BootstrapFixture::setUp();
-
- mxDesktop.set(frame::Desktop::create(mxComponentContext));
+ return uno::Reference<lang::XServiceInfo>(x, uno::UNO_QUERY_THROW)->supportsService(s);
}
-void TextFilterDetectTest::tearDown()
+/// Test class for PlainTextFilterDetect.
+class TextFilterDetectTest : public UnoApiTest
{
- if (mxComponent.is())
- mxComponent->dispose();
-
- test::BootstrapFixture::tearDown();
-}
-
-constexpr OUStringLiteral DATA_DIRECTORY = u"/filter/qa/unit/data/";
+public:
+ TextFilterDetectTest()
+ : UnoApiTest("/filter/qa/unit/data/")
+ {
+ }
+};
CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testTdf114428)
{
uno::Reference<document::XExtendedFilterDetection> xDetect(
getMultiServiceFactory()->createInstance("com.sun.star.comp.filters.PlainTextFilterDetect"),
uno::UNO_QUERY);
- OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf114428.xhtml";
+ OUString aURL = createFileURL(u"tdf114428.xhtml");
SvFileStream aStream(aURL, StreamMode::READ);
uno::Reference<io::XInputStream> xStream(new utl::OStreamWrapper(aStream));
uno::Sequence<beans::PropertyValue> aDescriptor
@@ -79,59 +72,167 @@ 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";
-
// When loading the file
- getComponent() = loadFromDesktop(aURL);
+ loadFromFile(u"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(mxComponent, "com.sun.star.presentation.PresentationDocument"));
// 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());
+ loadFromFile(u"empty.odt");
// Make sure it opens in Writer.
- CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextDocument"));
- getComponent()->dispose();
+ CPPUNIT_ASSERT(supportsService(mxComponent, "com.sun.star.text.TextDocument"));
+
+ // ... and ODS
+ loadFromFile(u"empty.ods");
+ // Make sure it opens in Calc.
+ CPPUNIT_ASSERT(supportsService(mxComponent, "com.sun.star.sheet.SpreadsheetDocument"));
// ... and ODP
- aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "empty.odp";
- getComponent() = loadFromDesktop(aURL);
- xServiceInfo.set(getComponent(), uno::UNO_QUERY);
- CPPUNIT_ASSERT(xServiceInfo.is());
+ loadFromFile(u"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(mxComponent, "com.sun.star.presentation.PresentationDocument"));
// ... 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);
+ loadFromFile(u"empty.doc");
+ CPPUNIT_ASSERT(supportsService(mxComponent, "com.sun.star.text.TextDocument"));
+ {
+ uno::Reference<frame::XModel> xModel(mxComponent, 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);
+ }
+
+ // Now test with default templates set
+
+ SfxObjectFactory::SetStandardTemplate("com.sun.star.presentation.PresentationDocument",
+ createFileURL(u"impress.otp"));
+ SfxObjectFactory::SetStandardTemplate("com.sun.star.text.TextDocument",
+ createFileURL(u"writer.ott"));
+ SfxObjectFactory::SetStandardTemplate("com.sun.star.sheet.SpreadsheetDocument",
+ createFileURL(u"calc.ots"));
+
+ loadFromFile(u"empty.pptx");
+ {
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, 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());
+ }
+
+ loadFromFile(u"empty.odt");
+ {
+ uno::Reference<text::XTextDocument> xDoc(mxComponent, 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(u"Writer template’s first line"_ustr, xParagraph->getString());
+ }
+
+ loadFromFile(u"empty.ods");
+ {
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, 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(u"Calc template’s first cell"_ustr, xC->getString());
+ }
+
+ loadFromFile(u"empty.odp");
+ {
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, 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());
+ }
+ loadFromFile(u"empty.doc");
+ {
+ uno::Reference<text::XTextDocument> xDoc(mxComponent, 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(u"Writer template’s first line"_ustr, xParagraph->getString());
+ }
+}
+
+// The unit test fails on some Linux systems. Until it is found out why the file URLs are broken
+// there, let it be Windows-only, since the original issue tested here was Windows-specific.
+// See https://lists.freedesktop.org/archives/libreoffice/2023-December/091265.html for details.
+#ifdef _WIN32
+CPPUNIT_TEST_FIXTURE(TextFilterDetectTest, testHybridPDFFile)
+{
+ // Make sure that file locking is ON
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::UseDocumentSystemFileLocking::set(true, xChanges);
+ xChanges->commit();
+ }
+
+ // Given a hybrid PDF file
+
+ {
+ // Created in Writer
+ utl::TempFileNamed nonAsciiName(u"абв_αβγ_");
+ nonAsciiName.EnableKillingFile();
+ CPPUNIT_ASSERT_EQUAL(
+ osl::FileBase::E_None,
+ osl::File::copy(createFileURL(u"hybrid_writer.pdf"), nonAsciiName.GetURL()));
+ load(nonAsciiName.GetURL());
+ // Make sure it opens in Writer.
+ // Without the accompanying fix in place, this test would have failed on Windows, as it was
+ // opened in Draw instead.
+ CPPUNIT_ASSERT(supportsService(mxComponent, "com.sun.star.text.TextDocument"));
+ }
+
+ {
+ // Created in Calc
+ utl::TempFileNamed nonAsciiName(u"абв_αβγ_");
+ nonAsciiName.EnableKillingFile();
+ CPPUNIT_ASSERT_EQUAL(
+ osl::FileBase::E_None,
+ osl::File::copy(createFileURL(u"hybrid_calc.pdf"), nonAsciiName.GetURL()));
+ load(nonAsciiName.GetURL());
+ // Make sure it opens in Calc.
+ CPPUNIT_ASSERT(supportsService(mxComponent, "com.sun.star.sheet.SpreadsheetDocument"));
+ }
+
+ {
+ // Created in Impress
+ utl::TempFileNamed nonAsciiName(u"абв_αβγ_");
+ nonAsciiName.EnableKillingFile();
+ CPPUNIT_ASSERT_EQUAL(
+ osl::FileBase::E_None,
+ osl::File::copy(createFileURL(u"hybrid_impress.pdf"), nonAsciiName.GetURL()));
+ load(nonAsciiName.GetURL());
+ // Make sure it opens in Impress.
+ CPPUNIT_ASSERT(
+ supportsService(mxComponent, "com.sun.star.presentation.PresentationDocument"));
+ }
}
+#endif // _WIN32
}
CPPUNIT_PLUGIN_IMPLEMENT();