From 267c6f2ac71f92999e969232431ba04678e7437e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 07:54:39 +0200 Subject: Adding upstream version 4:24.2.0. Signed-off-by: Daniel Baumann --- writerperfect/qa/unit/WpftLoader.cxx | 210 +++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 writerperfect/qa/unit/WpftLoader.cxx (limited to 'writerperfect/qa/unit/WpftLoader.cxx') diff --git a/writerperfect/qa/unit/WpftLoader.cxx b/writerperfect/qa/unit/WpftLoader.cxx new file mode 100644 index 0000000000..d0809b9099 --- /dev/null +++ b/writerperfect/qa/unit/WpftLoader.cxx @@ -0,0 +1,210 @@ +/* -*- 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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::test +{ +WpftLoader::WpftLoader(const OUString& rURL, + const css::uno::Reference& rxFilter, + const OUString& rFactoryURL, + const css::uno::Reference& rxDesktop, + const css::uno::Reference& rxTypeMap, + const css::uno::Reference& 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(const css::uno::Reference& rxInputStream, + const css::uno::Reference& rxFilter, + const OUString& rFactoryURL, + const css::uno::Reference& rxDesktop, + const css::uno::Reference& rxContext) + : m_xInputStream(rxInputStream) + , m_aFactoryURL(rFactoryURL) + , m_xFilter(rxFilter) + , m_xDesktop(rxDesktop) + , m_xContext(rxContext) +{ + if (!impl_load()) + impl_dispose(); +} + +WpftLoader::~WpftLoader() +{ + try + { + impl_dispose(); + } + catch (...) + { + } +} + +const css::uno::Reference& 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()), + uno::UNO_SET_THROW); + + // Find the model and frame. We need them later. + m_xFrame.set(m_xDoc, uno::UNO_QUERY); + uno::Reference xModel(m_xDoc, uno::UNO_QUERY); + uno::Reference 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 xImporter(m_xFilter, uno::UNO_QUERY_THROW); + + xImporter->setTargetDocument(m_xDoc); + + uno::Sequence aDescriptor(3); + auto pDescriptor = aDescriptor.getArray(); + pDescriptor[0].Name = "URL"; + pDescriptor[0].Value <<= m_aURL; + if (m_xInputStream.is()) + { + pDescriptor[1].Name = "InputStream"; + pDescriptor[1].Value <<= m_xInputStream; + } + else + { + ucbhelper::Content aContent(m_aURL, uno::Reference(), + m_xContext); + pDescriptor[1].Name = "InputStream"; + pDescriptor[1].Value <<= aContent.openStream(); + pDescriptor[2].Name = "UCBContent"; + pDescriptor[2].Value <<= aContent.get(); + } + + const uno::Reference xDetector(m_xFilter, + uno::UNO_QUERY_THROW); + + const OUString aTypeName(xDetector->detect(aDescriptor)); + if (aTypeName.isEmpty()) + throw lang::IllegalArgumentException(); + + if (m_xTypeMap.is()) + 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 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& rDescriptor, + const OUString& rTypeName) +{ + bool bHasFilterName + = std::any_of(std::cbegin(rDescriptor), std::cend(rDescriptor), + [](const beans::PropertyValue& rProp) { return "FilterName" == rProp.Name; }); + if (bHasFilterName) + return; + + uno::Sequence aTypes; + if (m_xTypeMap->getByName(rTypeName) >>= aTypes) + { + for (const auto& rType : std::as_const(aTypes)) + { + OUString aFilterName; + if (("PreferredFilter" == rType.Name) && (rType.Value >>= aFilterName)) + { + const sal_Int32 nDescriptorLen = rDescriptor.getLength(); + rDescriptor.realloc(nDescriptorLen + 1); + auto& el = rDescriptor.getArray()[nDescriptorLen]; + el.Name = "FilterName"; + el.Value <<= aFilterName; + return; + } + } + } + + throw container::NoSuchElementException(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3