Repository.mk | 1 filter/Configuration_filter.mk | 2 filter/source/config/fragments/filters/PowerPoint3.xcu | 28 filter/source/config/fragments/types/impress_PowerPoint3.xcu | 22 writerperfect/CppunitTest_writerperfect_calc.mk | 9 writerperfect/CppunitTest_writerperfect_draw.mk | 9 writerperfect/CppunitTest_writerperfect_impress.mk | 9 writerperfect/CppunitTest_writerperfect_writer.mk | 9 writerperfect/Library_wpftcalc.mk | 1 writerperfect/Library_wpftqahelper.mk | 41 + writerperfect/Library_writerperfect.mk | 1 writerperfect/Module_writerperfect.mk | 2 writerperfect/StaticLibrary_writerperfect_importtestbase.mk | 35 - writerperfect/inc/ImportFilter.hxx | 9 writerperfect/qa/unit/WpftCalcFilterTest.cxx | 6 writerperfect/qa/unit/WpftDrawFilterTest.cxx | 6 writerperfect/qa/unit/WpftFilterFixture.cxx | 47 + writerperfect/qa/unit/WpftFilterFixture.hxx | 84 ++ writerperfect/qa/unit/WpftFilterTestBase.cxx | 55 + writerperfect/qa/unit/WpftFilterTestBase.hxx | 72 ++ writerperfect/qa/unit/WpftImportTestBase.cxx | 218 ------- writerperfect/qa/unit/WpftImportTestBase.hxx | 117 ---- writerperfect/qa/unit/WpftImpressFilterTest.cxx | 10 writerperfect/qa/unit/WpftLoader.cxx | 194 ++++++ writerperfect/qa/unit/WpftLoader.hxx | 99 +++ writerperfect/qa/unit/WpftWriterFilterTest.cxx | 6 writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_3.ppt |binary writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_1 | 48 + writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_2 |binary writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_3 | 101 +++ writerperfect/qa/unit/wpftqahelperdllapi.h | 24 writerperfect/source/calc/MSWorksCalcImportFilter.cxx | 288 +++++++++- writerperfect/source/calc/MSWorksCalcImportFilter.hxx | 3 writerperfect/source/impress/MWAWPresentationImportFilter.cxx | 3 34 files changed, 1136 insertions(+), 423 deletions(-)
New commits: commit aef0cb825bdcda35013db701c9e3b3a23040349b Author: David Tardon <[email protected]> Date: Fri Dec 2 16:46:19 2016 +0100 drop unneeded dep on boost_headers Change-Id: I351badba30556ec06ebfa8a360cc58e89f206372 diff --git a/writerperfect/CppunitTest_writerperfect_calc.mk b/writerperfect/CppunitTest_writerperfect_calc.mk index 9093396..93ae3f3 100644 --- a/writerperfect/CppunitTest_writerperfect_calc.mk +++ b/writerperfect/CppunitTest_writerperfect_calc.mk @@ -9,10 +9,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,writerperfect_calc)) -$(eval $(call gb_CppunitTest_use_externals,writerperfect_calc,\ - boost_headers \ -)) - $(eval $(call gb_CppunitTest_use_sdk_api,writerperfect_calc)) $(eval $(call gb_CppunitTest_use_libraries,writerperfect_calc,\ diff --git a/writerperfect/CppunitTest_writerperfect_draw.mk b/writerperfect/CppunitTest_writerperfect_draw.mk index c614805..c7b5113 100644 --- a/writerperfect/CppunitTest_writerperfect_draw.mk +++ b/writerperfect/CppunitTest_writerperfect_draw.mk @@ -9,10 +9,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,writerperfect_draw)) -$(eval $(call gb_CppunitTest_use_externals,writerperfect_draw,\ - boost_headers \ -)) - $(eval $(call gb_CppunitTest_use_sdk_api,writerperfect_draw)) $(eval $(call gb_CppunitTest_use_libraries,writerperfect_draw,\ diff --git a/writerperfect/CppunitTest_writerperfect_impress.mk b/writerperfect/CppunitTest_writerperfect_impress.mk index dea8b38..52e4b6b 100644 --- a/writerperfect/CppunitTest_writerperfect_impress.mk +++ b/writerperfect/CppunitTest_writerperfect_impress.mk @@ -9,10 +9,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,writerperfect_impress)) -$(eval $(call gb_CppunitTest_use_externals,writerperfect_impress,\ - boost_headers \ -)) - $(eval $(call gb_CppunitTest_use_sdk_api,writerperfect_impress)) $(eval $(call gb_CppunitTest_use_libraries,writerperfect_impress,\ diff --git a/writerperfect/CppunitTest_writerperfect_writer.mk b/writerperfect/CppunitTest_writerperfect_writer.mk index 6e7aa5e..fc038a9 100644 --- a/writerperfect/CppunitTest_writerperfect_writer.mk +++ b/writerperfect/CppunitTest_writerperfect_writer.mk @@ -9,10 +9,6 @@ $(eval $(call gb_CppunitTest_CppunitTest,writerperfect_writer)) -$(eval $(call gb_CppunitTest_use_externals,writerperfect_writer,\ - boost_headers \ -)) - $(eval $(call gb_CppunitTest_use_sdk_api,writerperfect_writer)) $(eval $(call gb_CppunitTest_use_libraries,writerperfect_writer,\ diff --git a/writerperfect/Library_wpftqahelper.mk b/writerperfect/Library_wpftqahelper.mk index aefd206..86aa03a 100644 --- a/writerperfect/Library_wpftqahelper.mk +++ b/writerperfect/Library_wpftqahelper.mk @@ -19,7 +19,6 @@ $(eval $(call gb_Library_add_defs,wpftqahelper,\ )) $(eval $(call gb_Library_use_externals,wpftqahelper,\ - boost_headers \ cppunit \ )) diff --git a/writerperfect/Library_writerperfect.mk b/writerperfect/Library_writerperfect.mk index 98cb1e2..88b8421 100644 --- a/writerperfect/Library_writerperfect.mk +++ b/writerperfect/Library_writerperfect.mk @@ -29,7 +29,6 @@ $(eval $(call gb_Library_set_include,writerperfect, \ )) $(eval $(call gb_Library_use_externals,writerperfect,\ - boost_headers \ odfgen \ revenge \ )) commit 01c75db710126c88bcb6823386a8286a2a0de6fc Author: David Tardon <[email protected]> Date: Fri Dec 2 15:07:40 2016 +0100 convert test helper library to dynamic Change-Id: I5992cc7ac9ffb3974fa49bb7feec4b0212032386 diff --git a/Repository.mk b/Repository.mk index b5326e9..5f42a92 100644 --- a/Repository.mk +++ b/Repository.mk @@ -499,6 +499,7 @@ $(eval $(call gb_Helper_register_libraries,PLAINLIBS_NONE, \ vclbootstrapprotector \ scqahelper \ unowinreg \ + wpftqahelper \ $(if $(filter MSC,$(COM)),cli_cppuhelper) \ $(if $(filter $(OS),ANDROID),lo-bootstrap) \ $(if $(filter $(OS),MACOSX),OOoSpotlightImporter) \ diff --git a/writerperfect/CppunitTest_writerperfect_calc.mk b/writerperfect/CppunitTest_writerperfect_calc.mk index c7a8327..9093396 100644 --- a/writerperfect/CppunitTest_writerperfect_calc.mk +++ b/writerperfect/CppunitTest_writerperfect_calc.mk @@ -24,13 +24,10 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_calc,\ tl \ ucbhelper \ unotest \ + wpftqahelper \ $(gb_UWINAPI) \ )) -$(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_calc,\ - writerperfect_filtertestbase \ -)) - $(eval $(call gb_CppunitTest_use_ure,writerperfect_calc)) $(eval $(call gb_CppunitTest_use_vcl,writerperfect_calc)) diff --git a/writerperfect/CppunitTest_writerperfect_draw.mk b/writerperfect/CppunitTest_writerperfect_draw.mk index bd7a582..c614805 100644 --- a/writerperfect/CppunitTest_writerperfect_draw.mk +++ b/writerperfect/CppunitTest_writerperfect_draw.mk @@ -24,13 +24,10 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_draw,\ tl \ ucbhelper \ unotest \ + wpftqahelper \ $(gb_UWINAPI) \ )) -$(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_draw,\ - writerperfect_filtertestbase \ -)) - $(eval $(call gb_CppunitTest_use_ure,writerperfect_draw)) $(eval $(call gb_CppunitTest_use_vcl,writerperfect_draw)) diff --git a/writerperfect/CppunitTest_writerperfect_impress.mk b/writerperfect/CppunitTest_writerperfect_impress.mk index 352da2b..dea8b38 100644 --- a/writerperfect/CppunitTest_writerperfect_impress.mk +++ b/writerperfect/CppunitTest_writerperfect_impress.mk @@ -24,13 +24,10 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_impress,\ tl \ ucbhelper \ unotest \ + wpftqahelper \ $(gb_UWINAPI) \ )) -$(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_impress,\ - writerperfect_filtertestbase \ -)) - $(eval $(call gb_CppunitTest_use_ure,writerperfect_impress)) $(eval $(call gb_CppunitTest_use_vcl,writerperfect_impress)) diff --git a/writerperfect/CppunitTest_writerperfect_writer.mk b/writerperfect/CppunitTest_writerperfect_writer.mk index 3d20725..6e7aa5e 100644 --- a/writerperfect/CppunitTest_writerperfect_writer.mk +++ b/writerperfect/CppunitTest_writerperfect_writer.mk @@ -24,13 +24,10 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_writer,\ tl \ ucbhelper \ unotest \ + wpftqahelper \ $(gb_UWINAPI) \ )) -$(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_writer,\ - writerperfect_filtertestbase \ -)) - $(eval $(call gb_CppunitTest_use_ure,writerperfect_writer)) $(eval $(call gb_CppunitTest_use_vcl,writerperfect_writer)) diff --git a/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk b/writerperfect/Library_wpftqahelper.mk similarity index 57% rename from writerperfect/StaticLibrary_writerperfect_filtertestbase.mk rename to writerperfect/Library_wpftqahelper.mk index 8dec6fcf..aefd206 100644 --- a/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk +++ b/writerperfect/Library_wpftqahelper.mk @@ -7,28 +7,33 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -$(eval $(call gb_StaticLibrary_StaticLibrary,writerperfect_filtertestbase)) +$(eval $(call gb_Library_Library,wpftqahelper)) -$(eval $(call gb_StaticLibrary_set_include,writerperfect_filtertestbase,\ +$(eval $(call gb_Library_set_include,wpftqahelper,\ -I$(SRCDIR)/writerperfect/qa/unit \ $$(INCLUDE) \ )) -$(eval $(call gb_StaticLibrary_use_externals,writerperfect_filtertestbase,\ +$(eval $(call gb_Library_add_defs,wpftqahelper,\ + -DWPFTQAHELPER_DLLIMPLEMENTATION \ +)) + +$(eval $(call gb_Library_use_externals,wpftqahelper,\ boost_headers \ cppunit \ )) -$(eval $(call gb_StaticLibrary_use_sdk_api,writerperfect_filtertestbase)) +$(eval $(call gb_Library_use_sdk_api,wpftqahelper)) -$(eval $(call gb_StaticLibrary_use_libraries,writerperfect_filtertestbase,\ +$(eval $(call gb_Library_use_libraries,wpftqahelper,\ cppu \ sal \ test \ + ucbhelper \ unotest \ )) -$(eval $(call gb_StaticLibrary_add_exception_objects,writerperfect_filtertestbase,\ +$(eval $(call gb_Library_add_exception_objects,wpftqahelper,\ writerperfect/qa/unit/WpftFilterFixture \ writerperfect/qa/unit/WpftFilterTestBase \ writerperfect/qa/unit/WpftLoader \ diff --git a/writerperfect/Module_writerperfect.mk b/writerperfect/Module_writerperfect.mk index c6a3b04..eda54bb6 100644 --- a/writerperfect/Module_writerperfect.mk +++ b/writerperfect/Module_writerperfect.mk @@ -41,7 +41,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,writerperfect,\ CppunitTest_writerperfect_draw \ CppunitTest_writerperfect_impress \ CppunitTest_writerperfect_writer \ - StaticLibrary_writerperfect_filtertestbase \ + Library_wpftqahelper \ )) # vim: set noet sw=4 ts=4: diff --git a/writerperfect/qa/unit/WpftFilterFixture.hxx b/writerperfect/qa/unit/WpftFilterFixture.hxx index 4e45a38..fe8acc2 100644 --- a/writerperfect/qa/unit/WpftFilterFixture.hxx +++ b/writerperfect/qa/unit/WpftFilterFixture.hxx @@ -12,6 +12,8 @@ #include "config_writerperfect.h" +#include "wpftqahelperdllapi.h" + #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> @@ -63,7 +65,7 @@ namespace writerperfect namespace test { -class WpftFilterFixture : public ::test::BootstrapFixture +class WPFTQAHELPER_DLLPUBLIC WpftFilterFixture : public ::test::BootstrapFixture { public: virtual void setUp() override; diff --git a/writerperfect/qa/unit/WpftFilterTestBase.hxx b/writerperfect/qa/unit/WpftFilterTestBase.hxx index 7042daa..34aa728 100644 --- a/writerperfect/qa/unit/WpftFilterTestBase.hxx +++ b/writerperfect/qa/unit/WpftFilterTestBase.hxx @@ -10,6 +10,8 @@ #ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX #define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX +#include "wpftqahelperdllapi.h" + #include <unordered_map> #include <com/sun/star/uno/Reference.hxx> @@ -41,7 +43,7 @@ namespace test typedef std::unordered_map<rtl::OUString, bool, rtl::OUStringHash> WpftOptionalMap_t; -class WpftFilterTestBase +class WPFTQAHELPER_DLLPUBLIC WpftFilterTestBase : public ::test::FiltersTest , public WpftFilterFixture { diff --git a/writerperfect/qa/unit/WpftLoader.hxx b/writerperfect/qa/unit/WpftLoader.hxx index a854a53..97f2987 100644 --- a/writerperfect/qa/unit/WpftLoader.hxx +++ b/writerperfect/qa/unit/WpftLoader.hxx @@ -10,6 +10,8 @@ #ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTLOADER_HXX #define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTLOADER_HXX +#include "wpftqahelperdllapi.h" + #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Sequence.hxx> @@ -55,7 +57,7 @@ namespace writerperfect namespace test { -class WpftLoader +class WPFTQAHELPER_DLLPUBLIC WpftLoader { public: WpftLoader( diff --git a/writerperfect/qa/unit/wpftqahelperdllapi.h b/writerperfect/qa/unit/wpftqahelperdllapi.h new file mode 100644 index 0000000..9f19a29 --- /dev/null +++ b/writerperfect/qa/unit/wpftqahelperdllapi.h @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTQAHELPERDLLAPI_H +#define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTQAHELPERDLLAPI_H + +#include <sal/types.h> + +#if defined(WPFTQAHELPER_DLLIMPLEMENTATION) +#define WPFTQAHELPER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define WPFTQAHELPER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif +#define WPFTQAHELPER_DLLPRIVATE SAL_DLLPRIVATE + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit e60a60f570ec04eb1c0f94fe43675400f71c786f Author: David Tardon <[email protected]> Date: Fri Dec 2 15:01:17 2016 +0100 refactor Change-Id: I0cc034e7521de7911a9f5dfe8bc405971d175754 diff --git a/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk b/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk index 379964c..8dec6fcf 100644 --- a/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk +++ b/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk @@ -29,7 +29,9 @@ $(eval $(call gb_StaticLibrary_use_libraries,writerperfect_filtertestbase,\ )) $(eval $(call gb_StaticLibrary_add_exception_objects,writerperfect_filtertestbase,\ + writerperfect/qa/unit/WpftFilterFixture \ writerperfect/qa/unit/WpftFilterTestBase \ + writerperfect/qa/unit/WpftLoader \ )) # vim: set noet sw=4 ts=4: diff --git a/writerperfect/qa/unit/WpftFilterFixture.cxx b/writerperfect/qa/unit/WpftFilterFixture.cxx new file mode 100644 index 0000000..6ceb579 --- /dev/null +++ b/writerperfect/qa/unit/WpftFilterFixture.cxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "WpftFilterFixture.hxx" + +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/frame/theDesktop.hpp> + +namespace document = com::sun::star::document; +namespace frame = com::sun::star::frame; +namespace uno = com::sun::star::uno; + +namespace writerperfect +{ +namespace test +{ + +void WpftFilterFixture::setUp() +{ + ::test::BootstrapFixture::setUp(); + + m_xDesktop = frame::theDesktop::get(m_xContext); + + const uno::Reference<document::XTypeDetection> xTypeDetection( + m_xFactory->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext), + uno::UNO_QUERY_THROW); + m_xTypeMap.set(xTypeDetection, uno::UNO_QUERY_THROW); +} + +void WpftFilterFixture::tearDown() +{ + m_xDesktop->terminate(); + + ::test::BootstrapFixture::tearDown(); +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerperfect/qa/unit/WpftFilterFixture.hxx b/writerperfect/qa/unit/WpftFilterFixture.hxx new file mode 100644 index 0000000..4e45a38 --- /dev/null +++ b/writerperfect/qa/unit/WpftFilterFixture.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERFIXTURE_HXX +#define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERFIXTURE_HXX + +#include "config_writerperfect.h" + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/ustring.hxx> + +#include <test/bootstrapfixture.hxx> + +#define REQUIRE_VERSION(major, minor, micro, req_major, req_minor, req_micro) \ + (major) > (req_major) || \ + ((major) == (req_major) && \ + ((minor) > (req_minor) \ + || ((minor) == (req_minor) && ((micro) >= (req_micro))))) + +#define REQUIRE_EBOOK_VERSION(major, minor, micro) \ + REQUIRE_VERSION(EBOOK_VERSION_MAJOR, EBOOK_VERSION_MINOR, EBOOK_VERSION_MICRO, major, minor, micro) + +#define REQUIRE_ETONYEK_VERSION(major, minor, micro) \ + REQUIRE_VERSION(ETONYEK_VERSION_MAJOR, ETONYEK_VERSION_MINOR, ETONYEK_VERSION_MICRO, major, minor, micro) + +#define REQUIRE_MWAW_VERSION(major, minor, micro) \ + REQUIRE_VERSION(MWAW_VERSION_MAJOR, MWAW_VERSION_MINOR, MWAW_VERSION_MICRO, major, minor, micro) + +#define REQUIRE_STAROFFICE_VERSION(major, minor, micro) \ + REQUIRE_VERSION(STAROFFICE_VERSION_MAJOR, STAROFFICE_VERSION_MINOR, STAROFFICE_VERSION_MICRO, major, minor, micro) + +#define REQUIRE_WPS_VERSION(major, minor, micro) \ + REQUIRE_VERSION(WPS_VERSION_MAJOR, WPS_VERSION_MINOR, WPS_VERSION_MICRO, major, minor, micro) + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace container +{ +class XNameAccess; +} +namespace frame +{ +class XDesktop2; +} +} +} +} + +namespace writerperfect +{ +namespace test +{ + +class WpftFilterFixture : public ::test::BootstrapFixture +{ +public: + virtual void setUp() override; + virtual void tearDown() override; + +protected: + css::uno::Reference<css::frame::XDesktop2> m_xDesktop; + css::uno::Reference<css::container::XNameAccess> m_xTypeMap; +}; + +} +} + +#endif // INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERFIXTURE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerperfect/qa/unit/WpftFilterTestBase.cxx b/writerperfect/qa/unit/WpftFilterTestBase.cxx index c5b0eb6..a024334 100644 --- a/writerperfect/qa/unit/WpftFilterTestBase.cxx +++ b/writerperfect/qa/unit/WpftFilterTestBase.cxx @@ -7,38 +7,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <com/sun/star/beans/PropertyValue.hpp> -#include <com/sun/star/container/NoSuchElementException.hpp> -#include <com/sun/star/container/XNameAccess.hpp> -#include <com/sun/star/document/XExtendedFilterDetection.hpp> -#include <com/sun/star/document/XFilter.hpp> -#include <com/sun/star/document/XImporter.hpp> -#include <com/sun/star/document/XTypeDetection.hpp> -#include <com/sun/star/frame/theDesktop.hpp> -#include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/frame/XFrame.hpp> -#include <com/sun/star/frame/XModel.hpp> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/lang/IllegalArgumentException.hpp> -#include <com/sun/star/lang/XComponent.hpp> -#include <com/sun/star/ucb/XContent.hpp> -#include <com/sun/star/util/XCloseable.hpp> - -#include <tools/urlobj.hxx> +#include "WpftFilterTestBase.hxx" -#include <ucbhelper/content.hxx> +#include <com/sun/star/document/XFilter.hpp> -#include "WpftFilterTestBase.hxx" +#include "WpftLoader.hxx" -namespace beans = com::sun::star::beans; -namespace container = com::sun::star::container; -namespace document = com::sun::star::document; -namespace frame = com::sun::star::frame; -namespace io = com::sun::star::io; -namespace lang = com::sun::star::lang; -namespace ucb = com::sun::star::ucb; namespace uno = com::sun::star::uno; -namespace util = com::sun::star::util; namespace writerperfect { @@ -47,126 +22,17 @@ namespace test WpftFilterTestBase::WpftFilterTestBase(const rtl::OUString &rFactoryURL) : ::test::FiltersTest() - , ::test::BootstrapFixture() + , WpftFilterFixture() , m_aFactoryURL(rFactoryURL) - , m_xDesktop() - , m_xFilter() - , m_xTypeMap() , m_pOptionalMap(nullptr) { } -void WpftFilterTestBase::setUp() -{ - ::test::BootstrapFixture::setUp(); - - m_xDesktop = frame::theDesktop::get(m_xContext); - - const uno::Reference<document::XTypeDetection> xTypeDetection( - m_xFactory->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext), - uno::UNO_QUERY_THROW); - m_xTypeMap.set(xTypeDetection, uno::UNO_QUERY_THROW); -} - -void WpftFilterTestBase::tearDown() -{ - m_xDesktop->terminate(); - - ::test::BootstrapFixture::tearDown(); -} - bool WpftFilterTestBase::load(const OUString &, const OUString &rURL, const OUString &, SfxFilterFlags, SotClipboardFormatId, unsigned int) { - if (m_pOptionalMap) - { - // first check if this test file is supported by the used version of the library - const INetURLObject aUrl(rURL); - const WpftOptionalMap_t::const_iterator it(m_pOptionalMap->find(aUrl.getName())); - if ((it != m_pOptionalMap->end()) && !it->second) - return true; // skip the file - } - - // create an empty frame - const uno::Reference<lang::XComponent> xDoc( - m_xDesktop->loadComponentFromURL(m_aFactoryURL, "_blank", 0, uno::Sequence<beans::PropertyValue>()), - uno::UNO_QUERY_THROW); - - // Find the model and frame. We need them later. - uno::Reference<frame::XFrame> xFrame(xDoc, uno::UNO_QUERY); - uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY); - uno::Reference<frame::XController> xController(xDoc, uno::UNO_QUERY); - - if (xFrame.is()) - { - xController = xFrame->getController(); - xModel = xController->getModel(); - } - else if (xModel.is()) - { - xController = xModel->getCurrentController(); - xFrame = xController->getFrame(); - } - else if (xController.is()) - { - xFrame = xController->getFrame(); - xModel = xController->getModel(); - } - - if (!xFrame.is() || !xModel.is()) - throw uno::RuntimeException(); - - bool result = false; - - // try to import the document (and load it into the prepared frame) - try - { - const uno::Reference<document::XImporter> xImporter(m_xFilter, uno::UNO_QUERY_THROW); - - xImporter->setTargetDocument(xDoc); - - uno::Sequence<beans::PropertyValue> aDescriptor(3); - ucbhelper::Content aContent(rURL, uno::Reference<ucb::XCommandEnvironment>(), m_xContext); - - aDescriptor[0].Name = "URL"; - aDescriptor[0].Value <<= rURL; - aDescriptor[1].Name = "InputStream"; - aDescriptor[1].Value <<= aContent.openStream(); - aDescriptor[2].Name = "UCBContent"; - aDescriptor[2].Value <<= aContent.get(); - - const uno::Reference<document::XExtendedFilterDetection> xDetector(m_xFilter, uno::UNO_QUERY_THROW); - - const rtl::OUString aTypeName(xDetector->detect(aDescriptor)); - if (aTypeName.isEmpty()) - throw lang::IllegalArgumentException(); - - impl_detectFilterName(aDescriptor, aTypeName); - - xModel->lockControllers(); - result = m_xFilter->filter(aDescriptor); - xModel->unlockControllers(); - } - catch (const uno::Exception &) - { - // ignore - } - - // close the opened document - try - { - uno::Reference<util::XCloseable> xCloseable(xFrame, uno::UNO_QUERY); - if (xCloseable.is()) - xCloseable->close(true); - else - xDoc->dispose(); - } - catch (const uno::Exception &) - { - // ignore - } - - return result; + const WpftLoader aLoader(rURL, m_xFilter, m_aFactoryURL, m_xDesktop, m_xTypeMap, m_xContext); + return aLoader.getDocument().is(); } void WpftFilterTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath) @@ -183,35 +49,6 @@ void WpftFilterTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUStrin m_pOptionalMap = nullptr; } -void WpftFilterTestBase::impl_detectFilterName(uno::Sequence<beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName) -{ - const sal_Int32 nDescriptorLen = rDescriptor.getLength(); - - for (sal_Int32 n = 0; nDescriptorLen != n; ++n) - { - if ("FilterName" == rDescriptor[n].Name) - return; - } - - uno::Sequence<beans::PropertyValue> aTypes; - if (m_xTypeMap->getByName(rTypeName) >>= aTypes) - { - for (sal_Int32 n = 0; aTypes.getLength() != n; ++n) - { - rtl::OUString aFilterName; - if (("PreferredFilter" == aTypes[n].Name) && (aTypes[n].Value >>= aFilterName)) - { - rDescriptor.realloc(nDescriptorLen + 1); - rDescriptor[nDescriptorLen].Name = "FilterName"; - rDescriptor[nDescriptorLen].Value <<= aFilterName; - return; - } - } - } - - throw container::NoSuchElementException(); -} - } } diff --git a/writerperfect/qa/unit/WpftFilterTestBase.hxx b/writerperfect/qa/unit/WpftFilterTestBase.hxx index c6eb9c3..7042daa 100644 --- a/writerperfect/qa/unit/WpftFilterTestBase.hxx +++ b/writerperfect/qa/unit/WpftFilterTestBase.hxx @@ -10,39 +10,15 @@ #ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX #define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX -#include "config_writerperfect.h" - #include <unordered_map> #include <com/sun/star/uno/Reference.hxx> -#include <com/sun/star/uno/Sequence.hxx> #include <rtl/ustring.hxx> -#include <test/bootstrapfixture.hxx> - #include <unotest/filters-test.hxx> -#define REQUIRE_VERSION(major, minor, micro, req_major, req_minor, req_micro) \ - (major) > (req_major) || \ - ((major) == (req_major) && \ - ((minor) > (req_minor) \ - || ((minor) == (req_minor) && ((micro) >= (req_micro))))) - -#define REQUIRE_EBOOK_VERSION(major, minor, micro) \ - REQUIRE_VERSION(EBOOK_VERSION_MAJOR, EBOOK_VERSION_MINOR, EBOOK_VERSION_MICRO, major, minor, micro) - -#define REQUIRE_ETONYEK_VERSION(major, minor, micro) \ - REQUIRE_VERSION(ETONYEK_VERSION_MAJOR, ETONYEK_VERSION_MINOR, ETONYEK_VERSION_MICRO, major, minor, micro) - -#define REQUIRE_MWAW_VERSION(major, minor, micro) \ - REQUIRE_VERSION(MWAW_VERSION_MAJOR, MWAW_VERSION_MINOR, MWAW_VERSION_MICRO, major, minor, micro) - -#define REQUIRE_STAROFFICE_VERSION(major, minor, micro) \ - REQUIRE_VERSION(STAROFFICE_VERSION_MAJOR, STAROFFICE_VERSION_MINOR, STAROFFICE_VERSION_MICRO, major, minor, micro) - -#define REQUIRE_WPS_VERSION(major, minor, micro) \ - REQUIRE_VERSION(WPS_VERSION_MAJOR, WPS_VERSION_MINOR, WPS_VERSION_MICRO, major, minor, micro) +#include "WpftFilterFixture.hxx" namespace com { @@ -50,26 +26,10 @@ namespace sun { namespace star { -namespace beans -{ -struct PropertyValue; -} -namespace container -{ -class XNameAccess; -} namespace document { class XFilter; } -namespace frame -{ -class XDesktop2; -} -namespace ucb -{ -class XSimpleFileAccess; -} } } } @@ -83,14 +43,11 @@ typedef std::unordered_map<rtl::OUString, bool, rtl::OUStringHash> WpftOptionalM class WpftFilterTestBase : public ::test::FiltersTest - , public ::test::BootstrapFixture + , public WpftFilterFixture { public: explicit WpftFilterTestBase(const rtl::OUString &rFactoryURL); - virtual void setUp() override; - virtual void tearDown() override; - protected: void doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath); void doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath, const WpftOptionalMap_t &rOptionalMap); @@ -99,13 +56,9 @@ private: virtual bool load(const OUString &, const OUString &rURL, const OUString &, SfxFilterFlags, SotClipboardFormatId, unsigned int) override; - void impl_detectFilterName(css::uno::Sequence<css::beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName); - private: const rtl::OUString m_aFactoryURL; - css::uno::Reference<css::frame::XDesktop2> m_xDesktop; css::uno::Reference<css::document::XFilter> m_xFilter; - css::uno::Reference<css::container::XNameAccess> m_xTypeMap; const WpftOptionalMap_t *m_pOptionalMap; }; diff --git a/writerperfect/qa/unit/WpftLoader.cxx b/writerperfect/qa/unit/WpftLoader.cxx new file mode 100644 index 0000000..5299a27 --- /dev/null +++ b/writerperfect/qa/unit/WpftLoader.cxx @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "WpftLoader.hxx" + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/NoSuchElementException.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XDesktop2.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/util/XCloseable.hpp> + +#include <ucbhelper/content.hxx> + +namespace beans = com::sun::star::beans; +namespace container = com::sun::star::container; +namespace document = com::sun::star::document; +namespace frame = com::sun::star::frame; +namespace lang = com::sun::star::lang; +namespace ucb = com::sun::star::ucb; +namespace uno = com::sun::star::uno; +namespace util = com::sun::star::util; + +namespace writerperfect +{ +namespace test +{ + +WpftLoader::WpftLoader( + const rtl::OUString &rURL, + const css::uno::Reference<css::document::XFilter> &rxFilter, + const rtl::OUString &rFactoryURL, + const css::uno::Reference<css::frame::XDesktop2> &rxDesktop, + const css::uno::Reference<css::container::XNameAccess> &rxTypeMap, + const css::uno::Reference<css::uno::XComponentContext> &rxContext +) + : m_aURL(rURL) + , m_aFactoryURL(rFactoryURL) + , m_xFilter(rxFilter) + , m_xDesktop(rxDesktop) + , m_xTypeMap(rxTypeMap) + , m_xContext(rxContext) +{ + if (!impl_load()) + impl_dispose(); +} + +WpftLoader::~WpftLoader() +{ + try + { + impl_dispose(); + } + catch (...) + { + } +} + +const css::uno::Reference<css::lang::XComponent> &WpftLoader::getDocument() const +{ + return m_xDoc; +} + +bool WpftLoader::impl_load() +{ + // create an empty frame + m_xDoc.set( + m_xDesktop->loadComponentFromURL(m_aFactoryURL, "_blank", 0, uno::Sequence<beans::PropertyValue>()), + uno::UNO_QUERY_THROW); + + // Find the model and frame. We need them later. + m_xFrame.set(m_xDoc, uno::UNO_QUERY); + uno::Reference<frame::XModel> xModel(m_xDoc, uno::UNO_QUERY); + uno::Reference<frame::XController> xController(m_xDoc, uno::UNO_QUERY); + + if (m_xFrame.is()) + { + xController = m_xFrame->getController(); + xModel = xController->getModel(); + } + else if (xModel.is()) + { + xController = xModel->getCurrentController(); + m_xFrame = xController->getFrame(); + } + else if (xController.is()) + { + m_xFrame = xController->getFrame(); + xModel = xController->getModel(); + } + + if (!m_xFrame.is() || !xModel.is()) + throw uno::RuntimeException(); + + // try to import the document (and load it into the prepared frame) + try + { + const uno::Reference<document::XImporter> xImporter(m_xFilter, uno::UNO_QUERY_THROW); + + xImporter->setTargetDocument(m_xDoc); + + uno::Sequence<beans::PropertyValue> aDescriptor(3); + ucbhelper::Content aContent(m_aURL, uno::Reference<ucb::XCommandEnvironment>(), m_xContext); + + aDescriptor[0].Name = "URL"; + aDescriptor[0].Value <<= m_aURL; + aDescriptor[1].Name = "InputStream"; + aDescriptor[1].Value <<= aContent.openStream(); + aDescriptor[2].Name = "UCBContent"; + aDescriptor[2].Value <<= aContent.get(); + + const uno::Reference<document::XExtendedFilterDetection> xDetector(m_xFilter, uno::UNO_QUERY_THROW); + + const rtl::OUString aTypeName(xDetector->detect(aDescriptor)); + if (aTypeName.isEmpty()) + throw lang::IllegalArgumentException(); + + impl_detectFilterName(aDescriptor, aTypeName); + + xModel->lockControllers(); + const bool bLoaded = m_xFilter->filter(aDescriptor); + xModel->unlockControllers(); + return bLoaded; + } + catch (const uno::Exception &) + { + // ignore + } + + return false; +} + +void WpftLoader::impl_dispose() +{ + // close the opened document + uno::Reference<util::XCloseable> xCloseable(m_xFrame, uno::UNO_QUERY); + if (xCloseable.is()) + xCloseable->close(true); + else if (m_xDoc.is()) + m_xDoc->dispose(); + m_xDoc.clear(); + m_xFrame.clear(); +} + +void WpftLoader::impl_detectFilterName(uno::Sequence<beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName) +{ + const sal_Int32 nDescriptorLen = rDescriptor.getLength(); + + for (sal_Int32 n = 0; nDescriptorLen != n; ++n) + { + if ("FilterName" == rDescriptor[n].Name) + return; + } + + uno::Sequence<beans::PropertyValue> aTypes; + if (m_xTypeMap->getByName(rTypeName) >>= aTypes) + { + for (sal_Int32 n = 0; aTypes.getLength() != n; ++n) + { + rtl::OUString aFilterName; + if (("PreferredFilter" == aTypes[n].Name) && (aTypes[n].Value >>= aFilterName)) + { + rDescriptor.realloc(nDescriptorLen + 1); + rDescriptor[nDescriptorLen].Name = "FilterName"; + rDescriptor[nDescriptorLen].Value <<= aFilterName; + return; + } + } + } + + throw container::NoSuchElementException(); +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerperfect/qa/unit/WpftLoader.hxx b/writerperfect/qa/unit/WpftLoader.hxx new file mode 100644 index 0000000..a854a53 --- /dev/null +++ b/writerperfect/qa/unit/WpftLoader.hxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTLOADER_HXX +#define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTLOADER_HXX + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <rtl/ustring.hxx> + +namespace com +{ +namespace sun +{ +namespace star +{ +namespace beans +{ +struct PropertyValue; +} +namespace container +{ +class XNameAccess; +} +namespace document +{ +class XFilter; +} +namespace frame +{ +class XDesktop2; +class XFrame; +} +namespace lang +{ +class XComponent; +} +namespace uno +{ +class XComponentContext; +} +} +} +} + +namespace writerperfect +{ +namespace test +{ + +class WpftLoader +{ +public: + WpftLoader( + const rtl::OUString &rURL, + const css::uno::Reference<css::document::XFilter> &rxFilter, + const rtl::OUString &rFactoryURL, + const css::uno::Reference<css::frame::XDesktop2> &rxDesktop, + const css::uno::Reference<css::container::XNameAccess> &rxTypeMap, + const css::uno::Reference<css::uno::XComponentContext> &rxContext + ); + WpftLoader(const WpftLoader &) = delete; + WpftLoader &operator=(const WpftLoader &) = delete; + ~WpftLoader(); + + const css::uno::Reference<css::lang::XComponent> &getDocument() const; + +private: + bool impl_load(); + void impl_dispose(); + + void impl_detectFilterName(css::uno::Sequence<css::beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName); + +private: + const rtl::OUString m_aURL; + const rtl::OUString m_aFactoryURL; + const css::uno::Reference<css::document::XFilter> m_xFilter; + const css::uno::Reference<css::frame::XDesktop2> m_xDesktop; + const css::uno::Reference<css::container::XNameAccess> m_xTypeMap; + const css::uno::Reference<css::uno::XComponentContext> m_xContext; + css::uno::Reference<css::lang::XComponent> m_xDoc; + css::uno::Reference<css::frame::XFrame> m_xFrame; +}; + +} +} + +#endif // INCLUDED_WRITERPERFECT_QA_UNIT_WPFTLOADER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 675a74d5e57af8f6f3a30b69122cbd5faf392a86 Author: David Tardon <[email protected]> Date: Thu Dec 1 16:18:37 2016 +0100 rename to better match the purpose Change-Id: I7cd8e551c284045fbe782cc9756e283d466fd1bc diff --git a/writerperfect/CppunitTest_writerperfect_calc.mk b/writerperfect/CppunitTest_writerperfect_calc.mk index 04c8a2e..c7a8327 100644 --- a/writerperfect/CppunitTest_writerperfect_calc.mk +++ b/writerperfect/CppunitTest_writerperfect_calc.mk @@ -28,7 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_calc,\ )) $(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_calc,\ - writerperfect_importtestbase \ + writerperfect_filtertestbase \ )) $(eval $(call gb_CppunitTest_use_ure,writerperfect_calc)) diff --git a/writerperfect/CppunitTest_writerperfect_draw.mk b/writerperfect/CppunitTest_writerperfect_draw.mk index 24f7ce4..bd7a582 100644 --- a/writerperfect/CppunitTest_writerperfect_draw.mk +++ b/writerperfect/CppunitTest_writerperfect_draw.mk @@ -28,7 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_draw,\ )) $(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_draw,\ - writerperfect_importtestbase \ + writerperfect_filtertestbase \ )) $(eval $(call gb_CppunitTest_use_ure,writerperfect_draw)) diff --git a/writerperfect/CppunitTest_writerperfect_impress.mk b/writerperfect/CppunitTest_writerperfect_impress.mk index 9e85747..352da2b 100644 --- a/writerperfect/CppunitTest_writerperfect_impress.mk +++ b/writerperfect/CppunitTest_writerperfect_impress.mk @@ -28,7 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_impress,\ )) $(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_impress,\ - writerperfect_importtestbase \ + writerperfect_filtertestbase \ )) $(eval $(call gb_CppunitTest_use_ure,writerperfect_impress)) diff --git a/writerperfect/CppunitTest_writerperfect_writer.mk b/writerperfect/CppunitTest_writerperfect_writer.mk index e933700..3d20725 100644 --- a/writerperfect/CppunitTest_writerperfect_writer.mk +++ b/writerperfect/CppunitTest_writerperfect_writer.mk @@ -28,7 +28,7 @@ $(eval $(call gb_CppunitTest_use_libraries,writerperfect_writer,\ )) $(eval $(call gb_CppunitTest_use_static_libraries,writerperfect_writer,\ - writerperfect_importtestbase \ + writerperfect_filtertestbase \ )) $(eval $(call gb_CppunitTest_use_ure,writerperfect_writer)) diff --git a/writerperfect/Module_writerperfect.mk b/writerperfect/Module_writerperfect.mk index 860a213..c6a3b04 100644 --- a/writerperfect/Module_writerperfect.mk +++ b/writerperfect/Module_writerperfect.mk @@ -41,7 +41,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,writerperfect,\ CppunitTest_writerperfect_draw \ CppunitTest_writerperfect_impress \ CppunitTest_writerperfect_writer \ - StaticLibrary_writerperfect_importtestbase \ + StaticLibrary_writerperfect_filtertestbase \ )) # vim: set noet sw=4 ts=4: diff --git a/writerperfect/StaticLibrary_writerperfect_importtestbase.mk b/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk similarity index 57% rename from writerperfect/StaticLibrary_writerperfect_importtestbase.mk rename to writerperfect/StaticLibrary_writerperfect_filtertestbase.mk index bdd7970..379964c 100644 --- a/writerperfect/StaticLibrary_writerperfect_importtestbase.mk +++ b/writerperfect/StaticLibrary_writerperfect_filtertestbase.mk @@ -7,29 +7,29 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -$(eval $(call gb_StaticLibrary_StaticLibrary,writerperfect_importtestbase)) +$(eval $(call gb_StaticLibrary_StaticLibrary,writerperfect_filtertestbase)) -$(eval $(call gb_StaticLibrary_set_include,writerperfect_importtestbase,\ +$(eval $(call gb_StaticLibrary_set_include,writerperfect_filtertestbase,\ -I$(SRCDIR)/writerperfect/qa/unit \ $$(INCLUDE) \ )) -$(eval $(call gb_StaticLibrary_use_externals,writerperfect_importtestbase,\ +$(eval $(call gb_StaticLibrary_use_externals,writerperfect_filtertestbase,\ boost_headers \ cppunit \ )) -$(eval $(call gb_StaticLibrary_use_sdk_api,writerperfect_importtestbase)) +$(eval $(call gb_StaticLibrary_use_sdk_api,writerperfect_filtertestbase)) -$(eval $(call gb_StaticLibrary_use_libraries,writerperfect_importtestbase,\ +$(eval $(call gb_StaticLibrary_use_libraries,writerperfect_filtertestbase,\ cppu \ sal \ test \ unotest \ )) -$(eval $(call gb_StaticLibrary_add_exception_objects,writerperfect_importtestbase,\ - writerperfect/qa/unit/WpftImportTestBase \ +$(eval $(call gb_StaticLibrary_add_exception_objects,writerperfect_filtertestbase,\ + writerperfect/qa/unit/WpftFilterTestBase \ )) # vim: set noet sw=4 ts=4: diff --git a/writerperfect/qa/unit/WpftCalcFilterTest.cxx b/writerperfect/qa/unit/WpftCalcFilterTest.cxx index 98c4302..ce79995 100644 --- a/writerperfect/qa/unit/WpftCalcFilterTest.cxx +++ b/writerperfect/qa/unit/WpftCalcFilterTest.cxx @@ -7,12 +7,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "WpftImportTestBase.hxx" +#include "WpftFilterTestBase.hxx" namespace { -class WpftCalcFilterTest : public writerperfect::test::WpftImportTestBase +class WpftCalcFilterTest : public writerperfect::test::WpftFilterTestBase { public: WpftCalcFilterTest(); @@ -25,7 +25,7 @@ public: }; WpftCalcFilterTest::WpftCalcFilterTest() - : writerperfect::test::WpftImportTestBase("private:factory/scalc") + : writerperfect::test::WpftFilterTestBase("private:factory/scalc") { } diff --git a/writerperfect/qa/unit/WpftDrawFilterTest.cxx b/writerperfect/qa/unit/WpftDrawFilterTest.cxx index b2c9bb8..95a85c4 100644 --- a/writerperfect/qa/unit/WpftDrawFilterTest.cxx +++ b/writerperfect/qa/unit/WpftDrawFilterTest.cxx @@ -7,12 +7,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "WpftImportTestBase.hxx" +#include "WpftFilterTestBase.hxx" namespace { -class WpftDrawFilterTest : public writerperfect::test::WpftImportTestBase +class WpftDrawFilterTest : public writerperfect::test::WpftFilterTestBase { public: WpftDrawFilterTest(); @@ -25,7 +25,7 @@ public: }; WpftDrawFilterTest::WpftDrawFilterTest() - : writerperfect::test::WpftImportTestBase("private:factory/sdraw") + : writerperfect::test::WpftFilterTestBase("private:factory/sdraw") { } diff --git a/writerperfect/qa/unit/WpftImportTestBase.cxx b/writerperfect/qa/unit/WpftFilterTestBase.cxx similarity index 93% rename from writerperfect/qa/unit/WpftImportTestBase.cxx rename to writerperfect/qa/unit/WpftFilterTestBase.cxx index 66bc021..c5b0eb6 100644 --- a/writerperfect/qa/unit/WpftImportTestBase.cxx +++ b/writerperfect/qa/unit/WpftFilterTestBase.cxx @@ -28,7 +28,7 @@ #include <ucbhelper/content.hxx> -#include "WpftImportTestBase.hxx" +#include "WpftFilterTestBase.hxx" namespace beans = com::sun::star::beans; namespace container = com::sun::star::container; @@ -45,7 +45,7 @@ namespace writerperfect namespace test { -WpftImportTestBase::WpftImportTestBase(const rtl::OUString &rFactoryURL) +WpftFilterTestBase::WpftFilterTestBase(const rtl::OUString &rFactoryURL) : ::test::FiltersTest() , ::test::BootstrapFixture() , m_aFactoryURL(rFactoryURL) @@ -56,7 +56,7 @@ WpftImportTestBase::WpftImportTestBase(const rtl::OUString &rFactoryURL) { } -void WpftImportTestBase::setUp() +void WpftFilterTestBase::setUp() { ::test::BootstrapFixture::setUp(); @@ -68,14 +68,14 @@ void WpftImportTestBase::setUp() m_xTypeMap.set(xTypeDetection, uno::UNO_QUERY_THROW); } -void WpftImportTestBase::tearDown() +void WpftFilterTestBase::tearDown() { m_xDesktop->terminate(); ::test::BootstrapFixture::tearDown(); } -bool WpftImportTestBase::load(const OUString &, const OUString &rURL, const OUString &, +bool WpftFilterTestBase::load(const OUString &, const OUString &rURL, const OUString &, SfxFilterFlags, SotClipboardFormatId, unsigned int) { if (m_pOptionalMap) @@ -169,13 +169,13 @@ bool WpftImportTestBase::load(const OUString &, const OUString &rURL, const OUSt return result; } -void WpftImportTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath) +void WpftFilterTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath) { m_xFilter.set(m_xFactory->createInstanceWithContext(rFilter, m_xContext), uno::UNO_QUERY_THROW); testDir(OUString(), m_directories.getURLFromSrc(rPath)); } -void WpftImportTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath, const WpftOptionalMap_t &rOptionalMap) +void WpftFilterTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUString &rPath, const WpftOptionalMap_t &rOptionalMap) { m_xFilter.set(m_xFactory->createInstanceWithContext(rFilter, m_xContext), uno::UNO_QUERY_THROW); m_pOptionalMap = &rOptionalMap; @@ -183,7 +183,7 @@ void WpftImportTestBase::doTest(const rtl::OUString &rFilter, const rtl::OUStrin m_pOptionalMap = nullptr; } -void WpftImportTestBase::impl_detectFilterName(uno::Sequence<beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName) +void WpftFilterTestBase::impl_detectFilterName(uno::Sequence<beans::PropertyValue> &rDescriptor, const rtl::OUString &rTypeName) { const sal_Int32 nDescriptorLen = rDescriptor.getLength(); diff --git a/writerperfect/qa/unit/WpftImportTestBase.hxx b/writerperfect/qa/unit/WpftFilterTestBase.hxx similarity index 91% rename from writerperfect/qa/unit/WpftImportTestBase.hxx rename to writerperfect/qa/unit/WpftFilterTestBase.hxx index a3baec9..c6eb9c3 100644 --- a/writerperfect/qa/unit/WpftImportTestBase.hxx +++ b/writerperfect/qa/unit/WpftFilterTestBase.hxx @@ -7,8 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTIMPORTTESTBASE_HXX -#define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTIMPORTTESTBASE_HXX +#ifndef INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX +#define INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX #include "config_writerperfect.h" @@ -81,12 +81,12 @@ namespace test typedef std::unordered_map<rtl::OUString, bool, rtl::OUStringHash> WpftOptionalMap_t; -class WpftImportTestBase +class WpftFilterTestBase : public ::test::FiltersTest , public ::test::BootstrapFixture { public: - explicit WpftImportTestBase(const rtl::OUString &rFactoryURL); + explicit WpftFilterTestBase(const rtl::OUString &rFactoryURL); virtual void setUp() override; virtual void tearDown() override; @@ -112,6 +112,6 @@ private: } } -#endif // INCLUDED_WRITERPERFECT_QA_UNIT_WPFTIMPORTTESTBASE_HXX +#endif // INCLUDED_WRITERPERFECT_QA_UNIT_WPFTFILTERTESTBASE_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerperfect/qa/unit/WpftImpressFilterTest.cxx b/writerperfect/qa/unit/WpftImpressFilterTest.cxx index ce69dcd..5738c97 100644 --- a/writerperfect/qa/unit/WpftImpressFilterTest.cxx +++ b/writerperfect/qa/unit/WpftImpressFilterTest.cxx @@ -7,12 +7,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "WpftImportTestBase.hxx" +#include "WpftFilterTestBase.hxx" namespace { -class WpftImpressFilterTest : public writerperfect::test::WpftImportTestBase +class WpftImpressFilterTest : public writerperfect::test::WpftFilterTestBase { public: WpftImpressFilterTest(); @@ -25,7 +25,7 @@ public: }; WpftImpressFilterTest::WpftImpressFilterTest() - : writerperfect::test::WpftImportTestBase("private:factory/simpress") + : writerperfect::test::WpftFilterTestBase("private:factory/simpress") { } diff --git a/writerperfect/qa/unit/WpftWriterFilterTest.cxx b/writerperfect/qa/unit/WpftWriterFilterTest.cxx index 3e9c6ba..515a2b8 100644 --- a/writerperfect/qa/unit/WpftWriterFilterTest.cxx +++ b/writerperfect/qa/unit/WpftWriterFilterTest.cxx @@ -7,12 +7,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "WpftImportTestBase.hxx" +#include "WpftFilterTestBase.hxx" namespace { -class WpftWriterFilterTest : public writerperfect::test::WpftImportTestBase +class WpftWriterFilterTest : public writerperfect::test::WpftFilterTestBase { public: WpftWriterFilterTest(); @@ -25,7 +25,7 @@ public: }; WpftWriterFilterTest::WpftWriterFilterTest() - : writerperfect::test::WpftImportTestBase("private:factory/swriter") + : writerperfect::test::WpftFilterTestBase("private:factory/swriter") { } commit 7a4a6533e0313d6b8af448e2cc0de7b3fd5a493b Author: David Tardon <[email protected]> Date: Thu Dec 1 09:18:05 2016 +0100 simplify a bit Change-Id: Id56ba12c4c8c96285d95c48c4f49c93e4feec580 diff --git a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx index 62df1f9..e46b869 100644 --- a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx +++ b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx @@ -16,6 +16,7 @@ #include <com/sun/star/ucb/XContentAccess.hpp> #include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> +#include <tools/urlobj.hxx> #include <ucbhelper/content.hxx> #include <libwps/libwps.h> @@ -290,7 +291,7 @@ throw (css::uno::RuntimeException, std::exception) // time to check if the file is a WK3 file and a FM3 file is // present bool checkForFM3=false; - if (input.seek(0, librevenge::RVNG_SEEK_SET)==0 && xContent.is() && sUrl.getLength()>4) + if (input.seek(0, librevenge::RVNG_SEEK_SET)==0 && xContent.is() && INetURLObject(sUrl).getExtension().equalsIgnoreAsciiCase("WK3")) { // check if the file header corresponds to a .wk3 file unsigned long numBytesRead; @@ -299,58 +300,37 @@ throw (css::uno::RuntimeException, std::exception) data[3]==0 && data[4]<2 && data[5]==0x10) checkForFM3=true; } - OUString wk3Url; - if (checkForFM3) - { - // try to retrieve the base name - sal_Int32 idSlash=sUrl.lastIndexOf('/'); - if (idSlash!=-1) - { - wk3Url=sUrl.copy(idSlash+1); - checkForFM3=wk3Url.getLength()>4; - } - else - checkForFM3=false; - } - OUString fm3Url; - if (checkForFM3) - { - // check if the file extension corresponds to a .wk3 file and update the format expected name - if (wk3Url.endsWithAsciiL(".WK3", 4)) - fm3Url=wk3Url.copy(0,wk3Url.getLength()-4)+OUString(".FM3"); - else if (wk3Url.endsWithAsciiL(".wk3", 4)) - fm3Url=wk3Url.copy(0,wk3Url.getLength()-4)+OUString(".fm3"); - else - checkForFM3=false; - } if (checkForFM3) { // check if the format file exists const css::uno::Reference < container::XChild > xChild(xContent, uno::UNO_QUERY); if (xChild.is()) { - bool findFM3=false, findWK3=false; + rtl::OUString sWM3Name; + rtl::OUString sFM3Name; const css::uno::Reference < ucb::XContent > xPackageContent(xChild->getParent(), uno::UNO_QUERY); uno::Reference<sdbc::XResultSet> xResultSet=MSWorksCalcImportFilterInternal::getResultSet(xPackageContent); if (xResultSet.is() && xResultSet->first()) { const uno::Reference<ucb::XContentAccess> xContentAccess(xResultSet, uno::UNO_QUERY_THROW); const uno::Reference<sdbc::XRow> xRow(xResultSet, uno::UNO_QUERY_THROW); + INetURLObject aTmpUrl(sUrl); + sWM3Name = aTmpUrl.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET); + aTmpUrl.setExtension("FM3"); + const rtl::OUString &sTestFM3Name = aTmpUrl.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET); do { - const rtl::OUString aTitle(xRow->getString(1)); - if (aTitle == wk3Url) - findWK3=true; - else if (aTitle == fm3Url) - findFM3=true; + const rtl::OUString &aTitle(xRow->getString(1)); + if (aTitle.equalsIgnoreAsciiCase(sTestFM3Name)) + sFM3Name = aTitle; } - while (xResultSet->next() && (!findWK3 || !findFM3)); + while (xResultSet->next() && sFM3Name.isEmpty()); } - if (findWK3 && findFM3) + if (!sFM3Name.isEmpty()) { MSWorksCalcImportFilterInternal::FolderStream structuredInput(xPackageContent); - structuredInput.addFile(wk3Url,"WK3"); - structuredInput.addFile(fm3Url,"FM3"); + structuredInput.addFile(sWM3Name,"WK3"); + structuredInput.addFile(sFM3Name,"FM3"); // If the file is valid and libwps is at least 0.4.4, doImportDocument will convert it. // If libwps is at most 0.4.3, doImportDocument will fail when checking if the file is supported commit e51a5546ff3940866ff7cfeb4874accf69165501 Author: osnola <[email protected]> Date: Wed Nov 30 19:02:39 2016 +0100 try to retrieve the .fm3 file when reading a .wp3 file Change-Id: Ib2c2af423b92a65c08c2647a1e931ea54228c203 diff --git a/writerperfect/Library_wpftcalc.mk b/writerperfect/Library_wpftcalc.mk index 1748c3f8..311741d 100644 --- a/writerperfect/Library_wpftcalc.mk +++ b/writerperfect/Library_wpftcalc.mk @@ -36,6 +36,7 @@ $(eval $(call gb_Library_use_libraries,wpftcalc,\ sot \ svx \ tl \ + ucbhelper \ utl \ vcl \ writerperfect \ diff --git a/writerperfect/inc/ImportFilter.hxx b/writerperfect/inc/ImportFilter.hxx index 2b4b9bb..fa8f931 100644 --- a/writerperfect/inc/ImportFilter.hxx +++ b/writerperfect/inc/ImportFilter.hxx @@ -64,6 +64,11 @@ public: { } + const css::uno::Reference< css::uno::XComponentContext > &getXContext() const + { + return mxContext; + } + // XFilter virtual sal_Bool SAL_CALL filter(const css::uno::Sequence< css::beans::PropertyValue > &rDescriptor) throw (css::uno::RuntimeException, std::exception) override @@ -107,6 +112,10 @@ public: } // XImporter + const css::uno::Reference< css::lang::XComponent > &getTargetDocument() const + { + return mxDoc; + } virtual void SAL_CALL setTargetDocument(const css::uno::Reference< css::lang::XComponent > &xDoc) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) override { diff --git a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx index 5f049cf..62df1f9 100644 --- a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx +++ b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx @@ -9,7 +9,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <comphelper/processfactory.hxx> #include <cppuhelper/supportsservice.hxx> +#include <ucbhelper/content.hxx> #include <libwps/libwps.h> @@ -18,12 +25,169 @@ #include "MSWorksCalcImportFilter.hxx" #include "strings.hrc" -using com::sun::star::uno::Sequence; -using com::sun::star::uno::XInterface; -using com::sun::star::uno::Exception; -using com::sun::star::uno::RuntimeException; -using com::sun::star::uno::XComponentContext; +#include <iostream> +using namespace ::com::sun::star; + +using uno::Sequence; +using uno::XInterface; +using uno::Exception; +using uno::RuntimeException; +using uno::XComponentContext; + +namespace MSWorksCalcImportFilterInternal +{ + +/// returns the list of stream name present in a folder +uno::Reference<sdbc::XResultSet> getResultSet(const css::uno::Reference<css::ucb::XContent> &xPackageContent) +try +{ + if (xPackageContent.is()) + { + ucbhelper::Content packageContent(xPackageContent, uno::Reference<ucb::XCommandEnvironment>(), comphelper::getProcessComponentContext()); + uno::Sequence<OUString> lPropNames { "Title" }; + uno::Reference<sdbc::XResultSet> xResultSet(packageContent.createCursor(lPropNames, ucbhelper::INCLUDE_DOCUMENTS_ONLY)); + return xResultSet; + } + return uno::Reference<sdbc::XResultSet>(); +} +catch (...) +{ + SAL_WARN("writerperfect", "ignoring Exception in MSWorksCalcImportFilterInternal:getResultSet"); + return uno::Reference<sdbc::XResultSet>(); +} + +/** internal class used to create a structrured RVNGInputStream from a list of path and their short names + */ +class FolderStream: public librevenge::RVNGInputStream +{ +public: + //! constructor + explicit FolderStream(const css::uno::Reference<css::ucb::XContent> &xContent) : + librevenge::RVNGInputStream(), m_xContent(xContent), m_nameToPathMap() + { + } + + //! destructor + ~FolderStream() override + { + } + + //! add a file + void addFile(rtl::OUString const &path, std::string const &shortName) + { + m_nameToPathMap[shortName]=path; + } + /**! reads numbytes data. + + * \return a pointer to the read elements + */ + const unsigned char *read(unsigned long, unsigned long &) override + { + return nullptr; + } + //! returns actual offset position + long tell() override + { + return 0; + } + /*! \brief seeks to a offset position, from actual, beginning or ending position + * \return 0 if ok + */ + int seek(long , librevenge::RVNG_SEEK_TYPE) override + { + return 1; + } + //! returns true if we are at the end of the section/file + bool isEnd() override + { + return true; + } + + /** returns true if the stream is ole + + \sa returns always false*/ + bool isStructured() override + { + return true; + } + /** returns the number of sub streams. + + \sa returns always 2*/ + unsigned subStreamCount() override + { + return unsigned(m_nameToPathMap.size()); + } + /** returns the ith sub streams name */ + const char *subStreamName(unsigned id) override + { + std::map<std::string, rtl::OUString>::const_iterator it=m_nameToPathMap.begin(); + for (unsigned i=0; i<id; ++i) + { + if (it==m_nameToPathMap.end()) return nullptr; + ++it; + } + if (it==m_nameToPathMap.end()) return nullptr; + return it->first.c_str(); + } + /** returns true if a substream with name exists */ + bool existsSubStream(const char *name) override + { + return name && m_nameToPathMap.find(name)!= m_nameToPathMap.end(); + } + /** return a new stream for a ole zone */ + librevenge::RVNGInputStream *getSubStreamByName(const char *name) override +{ + if (m_nameToPathMap.find(name)== m_nameToPathMap.end() || !m_xContent.is()) return nullptr; + + try + { + const uno::Reference<sdbc::XResultSet> xResultSet=getResultSet(m_xContent); + if (xResultSet.is() && xResultSet->first()) + { + const uno::Reference<ucb::XContentAccess> xContentAccess(xResultSet, uno::UNO_QUERY_THROW); + const uno::Reference<sdbc::XRow> xRow(xResultSet, uno::UNO_QUERY_THROW); + OUString lPath=m_nameToPathMap.find(name)->second; + do + { + const rtl::OUString aTitle(xRow->getString(1)); + if (aTitle != lPath) continue; + + const uno::Reference<ucb::XContent> xSubContent(xContentAccess->queryContent()); + ucbhelper::Content aSubContent(xSubContent, uno::Reference<ucb::XCommandEnvironment>(), comphelper::getProcessComponentContext()); + uno::Reference<io::XInputStream> xInputStream = aSubContent.openStream(); + if (xInputStream.is()) + return new writerperfect::WPXSvInputStream(xInputStream); + break; + } + while (xResultSet->next()); + } + } + catch (...) + { + SAL_WARN("writerperfect", "ignoring Exception in MSWorksCalcImportFilterInternal::FolderStream::getSubStreamByName"); + } + + return nullptr; +} + /** return a new stream for a ole zone */ + librevenge::RVNGInputStream *getSubStreamById(unsigned id) override + { + char const *name=subStreamName(id); + return name ? getSubStreamByName(name) : nullptr; + } +private: + /// the main container + uno::Reference<ucb::XContent> m_xContent; + /// the map short name to path + std::map<std::string, rtl::OUString> m_nameToPathMap; + FolderStream(const FolderStream &) = delete; + FolderStream &operator=(const FolderStream &) = delete; +}; + +} + +//////////////////////////////////////////////////////////// bool MSWorksCalcImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdsGenerator &rGenerator, utl::MediaDescriptor &) { libwps::WPSKind kind = libwps::WPS_TEXT; @@ -67,14 +231,144 @@ bool MSWorksCalcImportFilter::doImportDocument(librevenge::RVNGInputStream &rInp else if (pDlg->hasUserCalledCancel()) return false; } - catch (css::uno::Exception &e) + catch (...) { - SAL_WARN("writerperfect", "ignoring Exception " << e.Message); + SAL_WARN("writerperfect", "ignoring Exception in MSWorksCalcImportFilter::doImportDocument"); } } return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator, "", fileEncoding.c_str()); } +//XExtendedFilterDetection +sal_Bool MSWorksCalcImportFilter::filter(const css::uno::Sequence< css::beans::PropertyValue > &rDescriptor) +throw (css::uno::RuntimeException, std::exception) +{ + OUString sUrl; + css::uno::Reference < css::io::XInputStream > xInputStream; + css::uno::Reference < ucb::XContent > xContent; + + sal_Int32 nLength = rDescriptor.getLength(); + const css::beans::PropertyValue *pValue = rDescriptor.getConstArray(); + for (sal_Int32 i = 0 ; i < nLength; i++) + { + if (pValue[i].Name == "InputStream") + pValue[i].Value >>= xInputStream; + else if (pValue[i].Name == "UCBContent") + pValue[i].Value >>= xContent; + else if (pValue[i].Name == "FileName" || pValue[i].Name == "URL") + pValue[i].Value >>= sUrl; + } + + if (!getXContext().is() || !xInputStream.is()) + { + OSL_ASSERT(false); + return false; + } + + // An XML import service: what we push sax messages to.. + css::uno::Reference < css::xml::sax::XDocumentHandler > xInternalHandler + (getXContext()->getServiceManager()->createInstanceWithContext + (writerperfect::DocumentHandlerFor<OdsGenerator>::name(), getXContext()), + css::uno::UNO_QUERY_THROW); + + // The XImporter sets up an empty target document for XDocumentHandler to write to.. + css::uno::Reference < css::document::XImporter > xImporter(xInternalHandler, css::uno::UNO_QUERY); + xImporter->setTargetDocument(getTargetDocument()); + + // OO Graphics Handler: abstract class to handle document SAX messages, concrete implementation here + // writes to in-memory target doc + writerperfect::DocumentHandler aHandler(xInternalHandler); + + writerperfect::WPXSvInputStream input(xInputStream); + OdsGenerator exporter; + exporter.addDocumentHandler(&aHandler, ODF_FLAT_XML); + this->doRegisterHandlers(exporter); + + utl::MediaDescriptor aDescriptor(rDescriptor); + try + { + // time to check if the file is a WK3 file and a FM3 file is + // present + bool checkForFM3=false; + if (input.seek(0, librevenge::RVNG_SEEK_SET)==0 && xContent.is() && sUrl.getLength()>4) + { + // check if the file header corresponds to a .wk3 file + unsigned long numBytesRead; + const unsigned char *data=input.read(6, numBytesRead); + if (data && numBytesRead==6 && data[0]==0 && data[1]==0 && data[2]==0x1a && + data[3]==0 && data[4]<2 && data[5]==0x10) + checkForFM3=true; + } + OUString wk3Url; + if (checkForFM3) + { + // try to retrieve the base name + sal_Int32 idSlash=sUrl.lastIndexOf('/'); + if (idSlash!=-1) + { + wk3Url=sUrl.copy(idSlash+1); + checkForFM3=wk3Url.getLength()>4; + } + else + checkForFM3=false; + } + OUString fm3Url; + if (checkForFM3) + { + // check if the file extension corresponds to a .wk3 file and update the format expected name + if (wk3Url.endsWithAsciiL(".WK3", 4)) + fm3Url=wk3Url.copy(0,wk3Url.getLength()-4)+OUString(".FM3"); + else if (wk3Url.endsWithAsciiL(".wk3", 4)) + fm3Url=wk3Url.copy(0,wk3Url.getLength()-4)+OUString(".fm3"); + else + checkForFM3=false; + } + if (checkForFM3) + { + // check if the format file exists + const css::uno::Reference < container::XChild > xChild(xContent, uno::UNO_QUERY); + if (xChild.is()) + { + bool findFM3=false, findWK3=false; + const css::uno::Reference < ucb::XContent > xPackageContent(xChild->getParent(), uno::UNO_QUERY); + uno::Reference<sdbc::XResultSet> xResultSet=MSWorksCalcImportFilterInternal::getResultSet(xPackageContent); + if (xResultSet.is() && xResultSet->first()) + { + const uno::Reference<ucb::XContentAccess> xContentAccess(xResultSet, uno::UNO_QUERY_THROW); + const uno::Reference<sdbc::XRow> xRow(xResultSet, uno::UNO_QUERY_THROW); + do + { + const rtl::OUString aTitle(xRow->getString(1)); + if (aTitle == wk3Url) + findWK3=true; + else if (aTitle == fm3Url) + findFM3=true; + } + while (xResultSet->next() && (!findWK3 || !findFM3)); + } + if (findWK3 && findFM3) + { + MSWorksCalcImportFilterInternal::FolderStream structuredInput(xPackageContent); + structuredInput.addFile(wk3Url,"WK3"); + structuredInput.addFile(fm3Url,"FM3"); + + // If the file is valid and libwps is at least 0.4.4, doImportDocument will convert it. + // If libwps is at most 0.4.3, doImportDocument will fail when checking if the file is supported + // and it is ok to call again doImportDocument with the main input. + // If the file is corrupted beyond all retrieval, doImportDocument will fail two times :-~ + if (this->doImportDocument(structuredInput, exporter, aDescriptor)) + return true; + } + } + } + } + catch (...) + { + } + + return this->doImportDocument(input, exporter, aDescriptor); +} + bool MSWorksCalcImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName) { libwps::WPSKind kind = libwps::WPS_TEXT; diff --git a/writerperfect/source/calc/MSWorksCalcImportFilter.hxx b/writerperfect/source/calc/MSWorksCalcImportFilter.hxx index 2ca720d..c209f6f 100644 --- a/writerperfect/source/calc/MSWorksCalcImportFilter.hxx +++ b/writerperfect/source/calc/MSWorksCalcImportFilter.hxx @@ -34,6 +34,9 @@ public: virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) override; + //XFilter + virtual sal_Bool SAL_CALL filter(const css::uno::Sequence< css::beans::PropertyValue > &rDescriptor) + throw (css::uno::RuntimeException, std::exception) override; private: virtual bool doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName) override; virtual bool doImportDocument(librevenge::RVNGInputStream &rInput, OdsGenerator &rGenerator, utl::MediaDescriptor &) override; commit 707c81bdba2d8145390cd3756dd93708d162b929 Author: David Tardon <[email protected]> Date: Wed Nov 30 18:37:14 2016 +0100 add separate MS PowerPoint 3 filter (libmwaw) Change-Id: I9f07e6d363387fc47f187f6635f489f8f8237f77 diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk index 2d36991..cbb951f3 100644 --- a/filter/Configuration_filter.mk +++ b/filter/Configuration_filter.mk @@ -601,6 +601,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_impress_types.xc impress_OOXML_Presentation_AutoPlay \ impress_ClarisWorks \ MWAW_Presentation \ + impress_PowerPoint3 \ )) $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_impress_filters.xcu,filter/source/config/fragments/filters,\ @@ -625,6 +626,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_impress_filter impress_OOXML_AutoPlay \ ClarisWorks_Impress \ MWAW_Presentation \ + PowerPoint3 \ )) # fcfg_chart diff --git a/filter/source/config/fragments/filters/PowerPoint3.xcu b/filter/source/config/fragments/filters/PowerPoint3.xcu new file mode 100644 index 0000000..c3675af --- /dev/null +++ b/filter/source/config/fragments/filters/PowerPoint3.xcu @@ -0,0 +1,28 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. +--> + +<node oor:name="PowerPoint 3" oor:op="replace"> + <prop oor:name="Flags"> + <value>IMPORT ALIEN 3RDPARTYFILTER</value> + </prop> + <prop oor:name="FilterService"> + <value>com.sun.star.comp.Impress.MWAWPresentationImportFilter</value> + </prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">Microsoft PowerPoint 3</value> + </prop> + <prop oor:name="FileFormatVersion"> + <value>0</value> + </prop> + <prop oor:name="Type"> + <value>impress_PowerPoint3</value> + </prop> + <prop oor:name="DocumentService"> + <value>com.sun.star.presentation.PresentationDocument</value> + </prop> +</node> diff --git a/filter/source/config/fragments/types/impress_PowerPoint3.xcu b/filter/source/config/fragments/types/impress_PowerPoint3.xcu new file mode 100644 index 0000000..5932b3a --- /dev/null +++ b/filter/source/config/fragments/types/impress_PowerPoint3.xcu @@ -0,0 +1,22 @@ +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. +--> + +<node oor:name="impress_PowerPoint3" oor:op="replace"> + <prop oor:name="DetectService"> + <value>com.sun.star.comp.Impress.MWAWPresentationImportFilter</value> + </prop> + <prop oor:name="Extensions"> + <value>ppt</value> + </prop> + <prop oor:name="PreferredFilter"> + <value>PowerPoint 3</value> + </prop> + <prop oor:name="UIName"> + <value>Microsoft PowerPoint 3</value> + </prop> +</node> diff --git a/writerperfect/source/impress/MWAWPresentationImportFilter.cxx b/writerperfect/source/impress/MWAWPresentationImportFilter.cxx index bca5ceb..e0e5d9a 100644 --- a/writerperfect/source/impress/MWAWPresentationImportFilter.cxx +++ b/writerperfect/source/impress/MWAWPresentationImportFilter.cxx @@ -58,6 +58,9 @@ bool MWAWPresentationImportFilter::doDetectFormat(librevenge::RVNGInputStream &r case MWAWDocument::MWAW_T_CLARISWORKS: rTypeName = "impress_ClarisWorks"; break; + case MWAWDocument::MWAW_T_RESERVED9: + rTypeName = "impress_PowerPoint3"; + break; default: rTypeName = "MWAW_Presentation"; break; commit 5c6dde9e4a8757807d4541be51f24cc3dfc53b14 Author: David Tardon <[email protected]> Date: Wed Nov 30 18:02:26 2016 +0100 add new test files for libmwaw 0.3.9 Change-Id: Ia8b69fac2115c9fd932c08deabe8908e07388d86 diff --git a/writerperfect/qa/unit/WpftImpressFilterTest.cxx b/writerperfect/qa/unit/WpftImpressFilterTest.cxx index 579fb9a..ce69dcd 100644 --- a/writerperfect/qa/unit/WpftImpressFilterTest.cxx +++ b/writerperfect/qa/unit/WpftImpressFilterTest.cxx @@ -40,6 +40,10 @@ void WpftImpressFilterTest::test() const writerperfect::test::WpftOptionalMap_t aMWAWOptional { {"ClarisWorks_6.0.cwk", REQUIRE_MWAW_VERSION(0, 3, 3)}, + {"PowerPoint_Mac_1", REQUIRE_MWAW_VERSION(0, 3, 9)}, + {"PowerPoint_Mac_2", REQUIRE_MWAW_VERSION(0, 3, 9)}, + {"PowerPoint_Mac_3", REQUIRE_MWAW_VERSION(0, 3, 9)}, + {"PowerPoint_3.ppt", REQUIRE_MWAW_VERSION(0, 3, 9)}, }; doTest("org.libreoffice.comp.Impress.KeynoteImportFilter", "/writerperfect/qa/unit/data/impress/libetonyek/", aEtonyekOptional); diff --git a/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_3.ppt b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_3.ppt new file mode 100644 index 0000000..f2185ab Binary files /dev/null and b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_3.ppt differ diff --git a/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_1 b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_1 new file mode 100644 index 0000000..72be750 --- /dev/null +++ b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_1 @@ -0,0 +1,48 @@ +(This file must be converted with BinHex 4.0) +:#R"[Gf9bF'pTER3!8da%8e"36P3"!!!!#DB!N!6iJ!ZYhZd!!!!#!!!!'!!D!!3 +!!!QQ!!S!'3!!!+J!!!$S!!!!rJ!!!C!!!!!!(!!!!Si!N!B#UJ!!!$S!!!+U!!! +"L!!!!Z3!!!"5!!!%E!!!!"`!!!5q!*!'"0S!!!!k!!!%fJ!!!"`!!!88!!!!'!! +!"6!!!!!i!!!&5!!!!"3!!!@!!!!!1J!!"C3!!!!a!!!&cJ!!!$%!!!Ar!!!!'!! +!"M!!!!&+!!!'5!!!!"J!!!H5!!!!&J!!"kS!!!"`!!!(`!!!!#!!!!J`!!!!1J! +!#&!!!!"i!!!)LJ!!!+!!!!N#rf6reIq#!#S$!*!%!3-"!*Mrr`!"!"N!E&E-rk$ +r4J!'!!B#!*!%!3%"!"6rr`!"!!8!E&GS!#ArC!!mrjF$!*!%!3%"!!$rr`!!!") +!E&GF!%MrA3"Yrj3$!!%!!!%%"3!!rrm!!!!5!'aAB!"irhB!VIrF!J#3"!%"!3! +!rrm!!`!#!'a@D!!Brli!J!%8!J!"!3!"!3-!!2rr!!)!!J"X8f3"!!!(FfaTC'8 +J-J%!"J!!'!%!&3!!!!4KBATK!!B!!")"!"8!!!!&BQ&kHQ80!!B!!")"!"8!!!! +%C'9PC!!'!!!5!3!9!!!!#`N*B3PKB@%*Bf&K$3!'!!!5!3!9!*!&"J!!%J%!&3! +!!!4KN!3!"J!!%J%!&3!!!!0MBf2J!!B!!")"!"8$!!!(E'PREQ8J-3!!"J!!%J% +!&3!!!!GXD@GZC5!b!3!'!!!5!3!9!3!!*f*TCb"kEfjP)''3'5"KN!6U!!B!!") +"!"8#!3!-#C!%B@%*#@'3"!!'!!!5!3!9rjMqZ3"Trp!"!*!&!3%!r`#3#[q3"!# +3"!%"!*!,!3#3"`B"!!!"9K3!'J!!!!-!N!8#!!'3"$3!m!%drf6re2q#!#`$!*! +%!3%"!*Mrr`!"!"N!E&EBrjVrL2qJ!&S!N!B"!3!!rrm!!3#3"[qqrdErk2pm!3% +"!!!!!J&"!2rr!!)!N!Erl[qX!",reJ'3"!!!#J-3!2rr!!%!N!FHrd!!92q#!3! +"!!%!"`%!!2rr!*!*0[qf!'8!BJ-!!3!!!3%%!!$rr`!!!#B!E&CJ!)6r8J#HrpB +#!*!%!3%"!!$rr`!!!!%!E&C)rm6rd2qQ!!`!N!B"!3%!rrm!!3#3"[r@rqJ!!!! +f!*!'!3%#!2rr!!%!N!F'!"J!*2rd!*!'!3%!'2rr!!%!N!Ff!%J!(J!H!*!'!3% +!!2rr!!%!N!EqL2lM!9N"*!%!N!8"!3$r!!)!N!MqP2l[!@8"-!%!N!8"!3$r!!) +!N!MrcIr+!"-!23%!N!8"!3"X!!-!N!J"!!!(8faTC'8J-3`!"J!!'!%!&3!!!"T +cE@&XE#"dCAKd$@)VG@jNCA*XD@jP+fpeG!!-!!!5!3!9!!X5$3!9!!!!"A4PH(3 +b!!!'!!!5!3!9rjMqZ3"Trp!"!*!&!3%!r`#3$33!N!8"!*!&E&0m!!!!"J#3"38 +!$J%!'2"1AL"I!!!!#!#3"3F!!3%"!!K3393Jrf6rYIq#!%S$!*!%!3%"!*Mrr`! +"!"N!E&G`!3!!$%eKFh4PFL"cE'PNC3!'!!!B!3!9rjMqZ3"Trp!"!*!&!3%!r`# +3#[qD!!!!'!#k!3!"!!!!!3%!&[rr!!%!%J"X9QJ"!!!)G'KP)'j[G'8!"J!!%J% +!&3!!!!N!N!8"!*!,#`#3"3S!!3%!,blr[UKG!!!!$3#3"3`!!J%!U&d3(m!I!$% +!N!3#d!*!%3'J!))"!!S!N!3#d!*!#J#3#$3!5!!Y!)J!QMLJ!)2r!$%!"`!(!%` +!H4%"S!##!3!+!!F!"`"-!(N+!*!)0!!+!!S!5J"h1+!!Jrm!"rq3"!#3"`)!!!! +2!!%!!!!3)!#3'K)!!!S2!6J!0J!N#Jm"!!"D!%J+$`&(!(i!E!S2!@i!SJ#3!!S +2!@F!!3!$!&%!G`#A!*!2"J!5!!!+#`%i!$B!*!S,!3!!@J")#JX"4`"q!'`+#`& +Z!+)!N!!+#`&R!!%!#J!)!"-!(!!N!$!!3!"3!&i!E!"f!$J!"!!-$"!"1!!f!#3 +-%!%!!&S!5!`3!8F!IJ"X$"!"EJ#L!*!!$"!"C`!"!!S!"`!0!"8!(3!M!#S!,J! +k!%8!8!29!")!!!S2!6J!0J!N#Jm"!!"D!%J+$`&(!(i!E!S2!@i!SJ#3!!S2!@F +!!!!+!!J!%`!F!#3!-!"!!&!!AJ"X!(B!1!!9!!`-%!%i!$B!*!`3!3!!@J")$"! +"4`"q!'`-%!&Z!+)!N!!-%!&R!"8!%J(!!"8!%J(!!"8!'!&""q%!I4NJ!!%!!!! +"!!%!EJ!!!3#3"#i!N!6qiIk*!5!"H!%!N!8"!3!-!*!+relr#J#Z!3J"!!%!!!! +"!8%!rrm!!3#3"[pHraB!VJ#k!*!'!3%!!2rr!!%!N!Er22mkre2rp3-!N!3"!3% +!!2rr!!!!%J"X9a!!!!!8G'9iG#"TEL"SB@jNEh9d)("KCf8!"J!!%J%!&5"Z!!j +$l[ri!*!+rrJL6#,B)YJ`,J!-8d$T30"81)!!!!!@!*!&&3!%!3"63%M!JI`!$`! +!!%J!5!#3"!,`!N$rmIrZ!`N#8Q-!"5J$r!%!!!!"D!&S!*!%$V!,3!!"!3!!C!! +"!!!!!3!#!!!!!5F2!!%!N!i3!*!*%!$rYIqQ$bd,QJ!)!3#3$4N"rrrr,IrrrX! +@aJ!!!#N!"3(F!R`!!J!#!*!&E&TB!!!!$J"X@1!!E&Pirbrqk3$5!4MqiIk*!5! +"H!!!!"F!E&D!rr!!"!!"!!8!!!!#!*!&2J"6!&F!3J!'!!N!#J)"!!!!E&CB!'a +9!!%#!!!!%3!!!")!!!!6rj!%!*!(&!)r!Zm"S`)Z!!%!J!!!!"J!N!J,VGlY$PB +!!!: diff --git a/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_2 b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_2 new file mode 100644 index 0000000..6f646c1 Binary files /dev/null and b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_2 differ diff --git a/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_3 b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_3 new file mode 100644 index 0000000..95b415b --- /dev/null +++ b/writerperfect/qa/unit/data/impress/libmwaw/pass/PowerPoint_Mac_3 @@ -0,0 +1,101 @@ +(This file must be converted with BinHex 4.0) +:"A"bCA-c!&0-4$038&3c!3!!!",*!!!%%fUe#khHl3!!!!-!!!!H!$`!#J!!%XN +!8!!l!*!'J!!!'!!!!Ik!!!"!!!!#&S!!N!8#9S!!N!8#9S!!!,)!!!*@J!!!*J! +!!`L!!!"!!!!$,S!!N!8$ES!!N!8$ES!!!'!!!!0ZJ!!!*J!!!mk!!!!J!!!$p)! +!!#!!!!38J!!!&J!!"$5!!!!B!!!%5S!!!%!!!!4LJ!#3"35LJ!#3"35LJ!!"iJ! +!"++!!!!Q!!!'K)!!!'!!!!DUJ!!!&!!!"`U!!*!&"ak!!!'q!!!((S!!!#B!!!M +FJ!!!)!!!#3+!!!!B!!!*)S!!!#!!!!NkJ!!!&!!!#9U!!*!&#@k!!!#8!!!*ES! +!!#B!!!S#J!!!)!!!#LL!!!!B!!!+5)!!!#!!!!TJJ!!!&!!!#S#!!*!&#T5!!!# +8!!!+P)!!!#B!!!XSJ!!!)!!!#dk!!!!5!!!,ES!!!"!!!!Z!J!!!'J!!#j!!J!! +!'J!!#kU!!!!D!!!,a)!!!$B!!![HJ!!!5!!!$"5!!!"!!!!-A)!!!&i!!!bFJ!! +!'!!!$2U!!!35!!!0%S!!!#)!!"%NJ!!!"J!!%8D!!!!-!!!46)!!!!F!!"&BJ!! +!$!!!%9q!!!!H!!!4Di!!!(J!!"'*J!!!0J!!%J'!!!#1!!!50`!!98i!!J!#rj! +%!!!(!J!-!*!'%!##d2N3pc$li!M3!3!"N!3!!J#3"2rp!!![0`i8%!##`2a`pc! +'N!!)d!%!!C!%!!)!N!6rr3!!)Pm#[!!!!!i!!!"J!*!&$J!!63#!!!!!q5hhD[[ +$#*B!!!!N!!%!!`!!,cF!rk8!N!4N!*!(!3"D!*!&!3!"!*!&$!#3"4!!N!8B!*! +&(!#3"34-!)!!!!$mMIGU"R-)PJ!!!"J!!3!"!*!%3!'P!*!%C!#3#9S!(J!!!!% +!!3#3"3`!N!83!*!&'!#3"4`!N!F%!!!!!3!#!!)!!3!!!!(r!*!1!J!!!!-3!), +!rh$jd!Q3!!B`!3!"N!3!!J#3"2rp!!"$E`Vd%"!!`2C`qQ$qi!@J!3!"N!3!!J# +3"2rp!!!"!*!+$Rrr!!!!$J!!6!#!!!!!rihk#JPc"IB!!!!-!!!!!3#3"IqP!*! +%C!#3#9S!+!!!!!%!!3#3"3`!N!83!*!&'!#3"4`!N!F*!!!!"J!#!!)!!3!"!!$ +r!*!1"`!!!!J!@($%!*!("3!!!!S!@CH%!*!'!3#3"J%!!!!+!!%!N!N$!*!%J3# +3#!Xm$!#3"``!!3!"!!!"!3"BF'3!!&91!!)!!J#3"JF#!!`!N!B3!),3q4$h-2[ +J#0!"!!'3"!!#!*!%rrd!!#*I$@33!),!r($h-!D3!!M3!3!"N!3!!J#3"2rp!!! +LA`fN!!!!$J!!!*J!N!81!!"0!)!!!!$j,IGUqm-)P[rr!#3!!Irr!!!Ii!$rP3$ +rr`"N!*!(!3"D!*!&!3!"!!!!#e0XD@4P)&4TG'aP!J!-!!!!#`!3!!!!!3!!!!X +!!!!N!!%!!`#3"4J!!!!,!"`!!!!"!!!!#`$rT3#3"'3!N!F"!&S!N!8"!!4-!)! +!!!$mMIGU"R-)P[rr!!i!!Irr!!!Ii%$rPJ$rr`"N!*!&"!!!!&S!(J#3"3%!!!! +l3QpNH5"8CAKd$90PBfpZC#"-CACPE!e8D'PbC#"-CACPE!e'Eh9bG'JJ6'9fC@` +04QPQG'JJ6'9fC@cS!!`!!!!l!"!!!!!$!!!!#J!!!"J!!3!"!*!('3!!!")!!3! +"!*!('!!!!!i!!3!"!*!&'!!!!$X!(!!!!!8!!!!+3!'P!*!%C!#3#9S!(J!!!!% +!!!!03!(3!*!%C!#3"3%!!!"D!"i!N!F-3!()!*!%C!#3"3)!!!"D!"i!N!F03!' +P!*!%C!#3"3-!!!"D!"i!N!F,3!(3!*!%C!#3"33!!!"D!"i!N!F5!!!!$`!#!!) +!!3!!!!(r!*!1%!!!!"%3!+6!#Lrr&JV2!1S"!!'3"!!#T!K[3rrp!!"$E`KF%"! +!d2C`qQ$qi!@J!3!!!3!"!!)!N!6rr3#3"K!!JX$rF2R3#C!!"M!"!!!"!!%!!J# +3"2rp!!"$E`HF)!!!'NB2!!!!$3!K!"`!0`!B!*!*P!#3"C3!"B`!J!!!!!T,rdd ++X`#crrm!#`!!rrm!!#4A!2q9!2rr!'3!N!F"!'3!-J#3"3%!!!!(8'&RC5!M)`! +!$!!!!!F!%!!!!!%!!!!(!!!!$!!!!!%!N!8B!!!!"`!F!!!!!3!!!!F!rk8!N!4 +N!*!(!3"D!*!)6!#!!!!!rihk#JPc"IErr`!-!!$rr`#3"Iq9!2rr!'3!N!8%!!! +!@J!S!!!!!3!"!!!!1d*[C(NJ9'9iG!e6C@0[EQ3J6'9fC@`09'KTFQ3J6'9fC@` +04QpeFR4S)%aPGQ9X$8CTCR4S)%aPGQ9X!!!-!!!!1`!3!!!!!3!!!$X!!!!-!!! +!!3#3"4J!!!!l!"`!!!!&!!!!#J$rT3#3"'3!N!PD!#J!!!!"!!!!$3$rT3#3"'3 +!N!8"!!!!@J!S!!!!!3!!!!`!rk8!N!4N!*!&!J!!!&S!+!!!!!%!!!!0!2qP!*! +%C!#3"3-!!!"D!#J!!!!"!!!!#`$rT3#3"'3!N!8%!!!!@J!S!!!!!3!!!"F!!!! +8!!-!!`!"!!%!!X-!N!i9!!!!&J"BEiJ!!!!1!!!!%`!!!"J!@9p-!&Q@U!!!!!% +!N!C96J!#!!)!N!B(!J!-!*!'%!#N`!S[raB+c`$U!3!"N!3!!U3%TcErr3!!0UF +%R#!!!"T'$`!!!!d!)3!F!$F!'!#3#R*N!!!!P!!&M!#!!!!!#N[r63Uc!,2rr`! +-!!$rr`!!'8X!rj8!rrm!C!#3"`%!@J#3"`%!!!!(8'&RC5!M)`!!$!!!!!F!%!! +!!!%!!!!(!!!!$!!!!!%!N!8B!!!!"`!F!!!!!3!!!!F!rk8!N!4N!*!(!3"D!*! +*(J!!!"X!!3!"!!(rN!8!N!iF!!!!(3"BFh3!!!!D!*!((`#3#`%!N!C96J!#!!) +!N!B(!J!-!*!'%!#N`!S[raB+c`$U!3!"N!3!!X`%TcErr3!!*SF$I#!!!"T'$`! +!!!d!)3!F!$F!'!#3#K!"!!!!P!!&M!#!!!!!#N[r63Uc!,2rr`!-!!$rr`!!b)B +!rj8!rrm!C!#3"`%!@J#3"`%!!!!(8'&RC5!M)`!!$!!!!!F!%!!!!!%!!!!(!!! +!$!!!!!%!N!8B!!!!"`!F!!!!!3!!!!F!rk8!N!4N!*!(!3"D!*!**3!!!#)!!3! +"!!(rN!8!N!iM!!!!*!"BEX`!!!!K!*!(*J#3#LSp!*!%J!%!F82D!!"rr`!!!!3 +!@0ld!!!!+!"aEeB!@@&-!&KZh!#3"!%J!5!#3!*!!f!$B!5!")!!!`*!!!!!Y!! +!!E!")!,3!N!$c!0J"1`%J!!$!N!!N!B"%J%5!L-#)`-e!c8%4J4'!!-#)`!!J!% +!F8`%!!Crr`!!!!3!@9pB!!F!!!!U!*!6!`!!!#X!!`!!!#`!!!QJJ!!!"`!U!#S +!N!3#@!#3"CJ!N$%)!!S!!!!Zm(i!!2"m!!$`I`!!q2m!!2rm!!$rrJ!!rrd!!2r +m!*!*!3!"!!%!!3!"!!%!!3!"!!$rr3#3"f3!C!"N!3%"!!iF0a8!!!QMJ!!!"`" +Brj!'!&N!N!F%N@L4D*&S!&N!N!G%B8H2@rhb!$-!!+i8!!!!$rcX!3BSpJ!&cYM +1f-lBJ!%!F8jS!!&rr`!!!!3!@9p-!!B!!!!`!&K`*!"BC4`!@'rX!!"0!)!I!!! +!*!!"!!-!N!FN!!%!!`#3"b3!!3!$!*!(*!!"!!-!N!FN!!%!!`#3"IqP!*!%C!# +3"`%!@J#3"3%!N!ArT3#3"'3!N!8"!!%!@J#3"3%!N!ArT3#3"'3!N!8#!!%!@J# +3"3%!N!ArT3#3"'3!N!8$!!%!@J#3"3%!N!ArT3#3"'3!N!8%!!%!@J#3"3%!N!8 +%6!#!(`!!!"J!!3!"!*!(%J!"!!%!N!F5!!%!!3#3"`i!!3!"!*!($J!"!!%!N!4 +!!D8!N!4N!*!*@J!H!!!!!3#3"%!"d!#3"'3!N!8"!!!!@J!H!*!)3!()!*!%C!# +3"3)!!!"D!"i!N!K!!D8!N!4N!*!&!`!!!&S!(J#3#%!"d!#3"'3!N!8%!!!!@J! +H!*!+6!#!(`!!!!`!!!!"!*!($!!!!!%!N!F-!!!!!3#3"``!!!!"!*!($!!!!!% +!N!ArT3#3"'3!N!PD!#J!!!!"!*!&rk8!N!4N!*!&!3!!!&S!+!!!!!%!N!ArT3# +3"'3!N!8#!!!!@J!S!!!!!3#3"IqP!*!%C!#3"3-!!!"D!#J!!!!"!*!&rk8!N!4 +N!*!&"!!!!&S!+!!!!!%!N!6rrd`!J"m!!3!B!!!!!3#3"3%!'!!!!!%!N!8"!"J +!!!!"!*!&!3!B!!!!!3#3"3%!'!!!!!%!N!48!D8!N!4N!*!*C!!8!*!)9!'P!*! +%C!#3"3%!!!"N!"3!N!K8!D8!N!4N!*!&!J!!!'3!&!#3#&3"T3#3"'3!N!8$!!! +!C!!8!*!)9!'P!*!%C!#3"33!!!"N!"3!N!V-!)!I!!!!%J!"!!%!N!F5!!%!!3# +3"a)!!3!"!*!(%J!"!!%!N!F5!!%!!3#3"IqP!*!%C!#3#@3!N![rT3#3"'3!N!P +N!*!,rk8!N!4N!*!*C!#3#rqP!*!%C!#3#@3!N![rT3#3"'3!N!PN!*!,!3!"!*! +(!3!!!3!#!#!!!$!!-!#3")!!N!8&3A*TB@`!!!!d!*!%rrm!!!C(C@jPGQ%!!!! +f!*!%rrm!1)!"!(&,f!!#Irm!!!!%!&PIE!!i!!!!03!&!!!!0`!$!!!!5!")!*! +%!YS#+2rKrq)#q3*'!dF&+!2m!!)!!!")!%J!N!3#fJ)S!!%!!!"N!!!!!3!"!3% +!!!!"*`m!!3!"!*!0!J!C!C!!!*!&3!#3#3%!N"%6!*!d!8J"Z!hJ%MMhN!$d`!K +`#d$d`2H3!!Y!#(!!N!Jj9!!!!!d!!!!R!!!!'3!!!#!!!!!kqC!!piJ!!Irr!!% +!!J!#!!-!N!FT!!!!,3!!!$%!!!![!!!!-`!!!$)!!!!i!*!%&S!3i"$J&S!!!3# +3"6RrN!3!!#F3!!!G62rq!!!!F3!$#khHlA@*!!!"!!!!!md!!!,0!!!!4L"(4#" +"8&"-!3#3&`9`FQ9c-`)!!!"66%3c8&"8-`%!rj!%!*!%#j`!N!466%3c8&"8-`% +!rj!%!*!5e#plA`!!%XN!!!36!*!-!TiP!8j238e"8&"-!3#3(3&1*3&6594P8dP +86!8!N"d"db8"BA4MEdGkDA$r!*!A!K)#%J#3"9X!H!!4![m-!2q3"!#3#AJ!!!" +E!*!(!3!+!*!&@`"i!*L!22r6rm3!,J!m!*!*5!!!!%J!N!8%!!%!"!#3"9KbZ!# +3"JDH!!!!$`!!rj!'!!%!N!6rr`!#!!#YD`!!!!-!!2rr!!!!"!!!rj!%!!9M')a +Mrrm!"T5PP+@8T3!(cR21Fmjc!!Mrr`#3"3Rrr`!!+8S!#[rr!!$rr`!,rj!%!!! +!$)3KK#'%)3!0cR21Fmjc!!jcR(1FFj`!$`#3"[r6rm3!,J!m!*!&@`"i!!!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3! +#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!#a3!!!2m!!!#cXP4SDA-JC'pMG@e +PER3JBfpeE'3JEQpd)'*P)'p`C@jPC#`JBQ9MBA9cC5"dD'8JBA"`E'PMBA4TEfi +JdP"[Gf9b8'pTER3J-bi`db"MEh9XC#"ZEh3JBQ8JCQpeEQ3Z)#"8D'Pc)'4[Bh9 +YC@jd)'0KEL"KE(0[)'*P)'p`C@jPC#"QFQpY)(GTG'KTEL"dD'8JdP"[Gf9b8'p +TER3J9QPPGf9bdb"KF("XD@0KG'P[ELi!!!%!!!!$c3!!!Xd!!!"'!&**`"6`!!! +!(!"'!!&35808!!!!%P088L!!!!!H4Errr`#3"9KXE,rcrrm!!!)@!&KbQ*qr: _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
