Bump version to 6.4-15
[LibreOffice.git] / writerperfect / qa / unit / WpftLoader.cxx
blobf29cd89c001fc61714fd4e8678abf31ce154fa01
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "WpftLoader.hxx"
12 #include <com/sun/star/beans/PropertyValue.hpp>
13 #include <com/sun/star/container/NoSuchElementException.hpp>
14 #include <com/sun/star/container/XNameAccess.hpp>
15 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
16 #include <com/sun/star/document/XFilter.hpp>
17 #include <com/sun/star/document/XImporter.hpp>
18 #include <com/sun/star/document/XTypeDetection.hpp>
19 #include <com/sun/star/frame/XController.hpp>
20 #include <com/sun/star/frame/XDesktop2.hpp>
21 #include <com/sun/star/frame/XModel.hpp>
22 #include <com/sun/star/io/XInputStream.hpp>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
26 #include <com/sun/star/ucb/XContent.hpp>
27 #include <com/sun/star/uno/XComponentContext.hpp>
28 #include <com/sun/star/util/XCloseable.hpp>
30 #include <ucbhelper/content.hxx>
32 namespace beans = com::sun::star::beans;
33 namespace container = com::sun::star::container;
34 namespace document = com::sun::star::document;
35 namespace frame = com::sun::star::frame;
36 namespace lang = com::sun::star::lang;
37 namespace ucb = com::sun::star::ucb;
38 namespace uno = com::sun::star::uno;
39 namespace util = com::sun::star::util;
41 namespace writerperfect
43 namespace test
45 WpftLoader::WpftLoader(const OUString& rURL,
46 const css::uno::Reference<css::document::XFilter>& rxFilter,
47 const OUString& rFactoryURL,
48 const css::uno::Reference<css::frame::XDesktop2>& rxDesktop,
49 const css::uno::Reference<css::container::XNameAccess>& rxTypeMap,
50 const css::uno::Reference<css::uno::XComponentContext>& rxContext)
51 : m_aURL(rURL)
52 , m_aFactoryURL(rFactoryURL)
53 , m_xFilter(rxFilter)
54 , m_xDesktop(rxDesktop)
55 , m_xTypeMap(rxTypeMap)
56 , m_xContext(rxContext)
58 if (!impl_load())
59 impl_dispose();
62 WpftLoader::WpftLoader(const css::uno::Reference<css::io::XInputStream>& rxInputStream,
63 const css::uno::Reference<css::document::XFilter>& rxFilter,
64 const OUString& rFactoryURL,
65 const css::uno::Reference<css::frame::XDesktop2>& rxDesktop,
66 const css::uno::Reference<css::uno::XComponentContext>& rxContext)
67 : m_xInputStream(rxInputStream)
68 , m_aFactoryURL(rFactoryURL)
69 , m_xFilter(rxFilter)
70 , m_xDesktop(rxDesktop)
71 , m_xContext(rxContext)
73 if (!impl_load())
74 impl_dispose();
77 WpftLoader::~WpftLoader()
79 try
81 impl_dispose();
83 catch (...)
88 const css::uno::Reference<css::lang::XComponent>& WpftLoader::getDocument() const { return m_xDoc; }
90 bool WpftLoader::impl_load()
92 // create an empty frame
93 m_xDoc.set(m_xDesktop->loadComponentFromURL(m_aFactoryURL, "_blank", 0,
94 uno::Sequence<beans::PropertyValue>()),
95 uno::UNO_SET_THROW);
97 // Find the model and frame. We need them later.
98 m_xFrame.set(m_xDoc, uno::UNO_QUERY);
99 uno::Reference<frame::XModel> xModel(m_xDoc, uno::UNO_QUERY);
100 uno::Reference<frame::XController> xController(m_xDoc, uno::UNO_QUERY);
102 if (m_xFrame.is())
104 xController = m_xFrame->getController();
105 xModel = xController->getModel();
107 else if (xModel.is())
109 xController = xModel->getCurrentController();
110 m_xFrame = xController->getFrame();
112 else if (xController.is())
114 m_xFrame = xController->getFrame();
115 xModel = xController->getModel();
118 if (!m_xFrame.is() || !xModel.is())
119 throw uno::RuntimeException();
121 // try to import the document (and load it into the prepared frame)
124 const uno::Reference<document::XImporter> xImporter(m_xFilter, uno::UNO_QUERY_THROW);
126 xImporter->setTargetDocument(m_xDoc);
128 uno::Sequence<beans::PropertyValue> aDescriptor(3);
129 aDescriptor[0].Name = "URL";
130 aDescriptor[0].Value <<= m_aURL;
131 if (m_xInputStream.is())
133 aDescriptor[1].Name = "InputStream";
134 aDescriptor[1].Value <<= m_xInputStream;
136 else
138 ucbhelper::Content aContent(m_aURL, uno::Reference<ucb::XCommandEnvironment>(),
139 m_xContext);
140 aDescriptor[1].Name = "InputStream";
141 aDescriptor[1].Value <<= aContent.openStream();
142 aDescriptor[2].Name = "UCBContent";
143 aDescriptor[2].Value <<= aContent.get();
146 const uno::Reference<document::XExtendedFilterDetection> xDetector(m_xFilter,
147 uno::UNO_QUERY_THROW);
149 const OUString aTypeName(xDetector->detect(aDescriptor));
150 if (aTypeName.isEmpty())
151 throw lang::IllegalArgumentException();
153 if (m_xTypeMap.is())
154 impl_detectFilterName(aDescriptor, aTypeName);
156 xModel->lockControllers();
157 const bool bLoaded = m_xFilter->filter(aDescriptor);
158 xModel->unlockControllers();
159 return bLoaded;
161 catch (const uno::Exception&)
163 // ignore
166 return false;
169 void WpftLoader::impl_dispose()
171 // close the opened document
172 uno::Reference<util::XCloseable> xCloseable(m_xFrame, uno::UNO_QUERY);
173 if (xCloseable.is())
174 xCloseable->close(true);
175 else if (m_xDoc.is())
176 m_xDoc->dispose();
177 m_xDoc.clear();
178 m_xFrame.clear();
181 void WpftLoader::impl_detectFilterName(uno::Sequence<beans::PropertyValue>& rDescriptor,
182 const OUString& rTypeName)
184 bool bHasFilterName
185 = std::any_of(rDescriptor.begin(), rDescriptor.end(),
186 [](const beans::PropertyValue& rProp) { return "FilterName" == rProp.Name; });
187 if (bHasFilterName)
188 return;
190 uno::Sequence<beans::PropertyValue> aTypes;
191 if (m_xTypeMap->getByName(rTypeName) >>= aTypes)
193 for (const auto& rType : std::as_const(aTypes))
195 OUString aFilterName;
196 if (("PreferredFilter" == rType.Name) && (rType.Value >>= aFilterName))
198 const sal_Int32 nDescriptorLen = rDescriptor.getLength();
199 rDescriptor.realloc(nDescriptorLen + 1);
200 rDescriptor[nDescriptorLen].Name = "FilterName";
201 rDescriptor[nDescriptorLen].Value <<= aFilterName;
202 return;
207 throw container::NoSuchElementException();
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */