LibreOffice Module uui (master) 1
iahndl-filter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/beans/XPropertyAccess.hpp>
21#include <com/sun/star/container/XContainerQuery.hpp>
22#include <com/sun/star/container/XNameAccess.hpp>
23#include <com/sun/star/document/FilterOptionsRequest.hpp>
24#include <com/sun/star/document/NoSuchFilterRequest.hpp>
25#include <com/sun/star/document/XImporter.hpp>
26#include <com/sun/star/document/XInteractionFilterOptions.hpp>
27#include <com/sun/star/document/XInteractionFilterSelect.hpp>
28#include <com/sun/star/task/XInteractionAbort.hpp>
29#include <com/sun/star/task/XInteractionRequest.hpp>
30#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
31
34#include <vcl/svapp.hxx>
35
36#include "getcontinuations.hxx"
37#include "fltdlg.hxx"
38
39#include "iahndl.hxx"
40
41using namespace com::sun::star;
42
43namespace {
44
45void
46executeFilterDialog(
47 weld::Window* pParent ,
48 OUString const & rURL ,
49 uui::FilterNameList const & rFilters,
50 OUString & rFilter )
51{
52 SolarMutexGuard aGuard;
53
54 uui::FilterDialog aDialog(pParent);
55
56 aDialog.SetURL(rURL);
57 aDialog.ChangeFilters(&rFilters);
58
59 uui::FilterNameListPtr pSelected = rFilters.end();
60 if (aDialog.AskForFilter(pSelected))
61 {
62 rFilter = pSelected->sInternal;
63 }
64}
65
66void
67handleNoSuchFilterRequest_(
68 weld::Window* pParent,
69 uno::Reference< uno::XComponentContext > const & xContext,
70 document::NoSuchFilterRequest const & rRequest,
71 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
72 rContinuations )
73{
74 uno::Reference< task::XInteractionAbort > xAbort;
75 uno::Reference< document::XInteractionFilterSelect > xFilterTransport;
76 getContinuations(rContinuations, &xAbort, &xFilterTransport);
77
78 // check necessary resources - if they don't exist - abort or
79 // break this operation
80 if (!xAbort.is())
81 return;
82
83 if (!xFilterTransport.is())
84 {
85 xAbort->select();
86 return;
87 }
88
89 uno::Reference< container::XContainerQuery > xFilterContainer;
90 try
91 {
92 xFilterContainer.set( xContext->getServiceManager()->createInstanceWithContext(
93 "com.sun.star.document.FilterFactory", xContext ),
94 uno::UNO_QUERY );
95 }
96 catch ( uno::Exception const & )
97 {
98 }
99
100 if (!xFilterContainer.is())
101 {
102 xAbort->select();
103 return;
104 }
105
106 uui::FilterNameList lNames;
107
108 // Note: We look for all filters here which match the following criteria:
109 // - they are import filters as minimum (of course they can
110 // support export too)
111 // - we don't show any filter which are flagged as "don't show it
112 // at the UI" or "they are not installed"
113 // - we ignore filters, which have not set any valid
114 // DocumentService (e.g. our pure graphic filters)
115 // - we show it sorted by her UIName's
116 // - We don't use the order flag or prefer default filters.
117 // (Because this list shows all filters and the user should
118 // find his filter very easy by his UIName ...)
119 // - We use "_query_all" here ... but we filter graphic filters
120 // out by using DocumentService property later!
121 uno::Reference< container::XEnumeration > xFilters
122 = xFilterContainer->createSubSetEnumerationByQuery(
123 "_query_all:sort_prop=uiname:iflags=1:eflags=143360");
124 while (xFilters->hasMoreElements())
125 {
126 try
127 {
128 ::comphelper::SequenceAsHashMap lProps(xFilters->nextElement());
130
131 aPair.sInternal = lProps.getUnpackedValueOrDefault(
132 "Name", OUString());
133 aPair.sUI = lProps.getUnpackedValueOrDefault(
134 "UIName", OUString());
135 if ( aPair.sInternal.isEmpty() || aPair.sUI.isEmpty() )
136 {
137 continue;
138 }
139 lNames.push_back( aPair );
140 }
141 catch(const uno::RuntimeException&)
142 {
143 throw;
144 }
145 catch(const uno::Exception&)
146 {
147 continue;
148 }
149 }
150
151 // no list available for showing
152 // -> abort operation
153 if (lNames.empty())
154 {
155 xAbort->select();
156 return;
157 }
158
159 // let the user select the right filter
160 OUString sSelectedFilter;
161 executeFilterDialog( pParent,
162 rRequest.URL,
163 lNames,
164 sSelectedFilter );
165
166 // If he doesn't select anyone
167 // -> abort operation
168 if (sSelectedFilter.isEmpty())
169 {
170 xAbort->select();
171 return;
172 }
173
174 // otherwise set it for return
175 xFilterTransport->setFilter( sSelectedFilter );
176 xFilterTransport->select();
177}
178
179void
180handleFilterOptionsRequest_(
181 uno::Reference<awt::XWindow> const & rWindow,
182 uno::Reference< uno::XComponentContext > const & xContext,
183 document::FilterOptionsRequest const & rRequest,
184 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
185 rContinuations)
186{
187 uno::Reference< task::XInteractionAbort > xAbort;
188 uno::Reference< document::XInteractionFilterOptions > xFilterOptions;
189 getContinuations(rContinuations, &xAbort, &xFilterOptions);
190
191 uno::Reference< container::XNameAccess > xFilterCFG;
192 try
193 {
194 xFilterCFG.set( xContext->getServiceManager()->createInstanceWithContext(
195 "com.sun.star.document.FilterFactory", xContext ),
196 uno::UNO_QUERY );
197 }
198 catch ( uno::Exception const & )
199 {
200 }
201
202 if( xFilterCFG.is() && rRequest.rProperties.hasElements() )
203 {
204 try
205 {
206 OUString aFilterName;
207 auto pProperty = std::find_if(rRequest.rProperties.begin(), rRequest.rProperties.end(),
208 [](const beans::PropertyValue& rProp) { return rProp.Name == "FilterName"; });
209 if (pProperty != rRequest.rProperties.end())
210 {
211 pProperty->Value >>= aFilterName;
212 }
213
214 uno::Sequence < beans::PropertyValue > aProps;
215 if ( xFilterCFG->getByName( aFilterName ) >>= aProps )
216 {
217 auto pProp = std::find_if(std::cbegin(aProps), std::cend(aProps),
218 [](const beans::PropertyValue& rProp) { return rProp.Name == "UIComponent"; });
219 if (pProp != std::cend(aProps))
220 {
221 OUString aServiceName;
222 pProp->Value >>= aServiceName;
223 if( !aServiceName.isEmpty() )
224 {
225 uno::Sequence<uno::Any> aDialogArgs(comphelper::InitAnyPropertySequence(
226 {
227 {"ParentWindow", uno::Any(rWindow)},
228 }));
229
230 uno::Reference<
231 ui::dialogs::XExecutableDialog > xFilterDialog(
232 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
233 aServiceName, aDialogArgs, xContext ),
234 uno::UNO_QUERY );
235
236 uno::Reference< beans::XPropertyAccess >
237 xFilterProperties( xFilterDialog,
238 uno::UNO_QUERY );
239
240 if( xFilterDialog.is() && xFilterProperties.is() )
241 {
242 uno::Reference<
243 document::XImporter > xImporter(
244 xFilterDialog, uno::UNO_QUERY );
245 if( xImporter.is() )
246 xImporter->setTargetDocument( rRequest.rModel );
247
248 xFilterProperties->setPropertyValues(
249 rRequest.rProperties );
250
251 if( xFilterDialog->execute() )
252 {
253 xFilterOptions->setFilterOptions(
254 xFilterProperties->getPropertyValues() );
255 xFilterOptions->select();
256 return;
257 }
258 }
259 }
260 }
261 }
262 }
263 catch( container::NoSuchElementException& )
264 {
265 // the filter name is unknown
266 }
267 catch( uno::Exception& )
268 {
269 }
270 }
271
272 xAbort->select();
273}
274
275} // namespace
276
277bool
279 uno::Reference< task::XInteractionRequest > const & rRequest)
280{
281 uno::Any aAnyRequest(rRequest->getRequest());
282
283 document::NoSuchFilterRequest aNoSuchFilterRequest;
284 if (aAnyRequest >>= aNoSuchFilterRequest)
285 {
286 uno::Reference<awt::XWindow> xParent = getParentXWindow();
287 handleNoSuchFilterRequest_(Application::GetFrameWeld(xParent),
289 aNoSuchFilterRequest,
290 rRequest->getContinuations());
291 return true;
292 }
293 return false;
294}
295
296bool
298 uno::Reference< task::XInteractionRequest > const & rRequest)
299{
300 uno::Any aAnyRequest(rRequest->getRequest());
301
302 document::FilterOptionsRequest aFilterOptionsRequest;
303 if (aAnyRequest >>= aFilterOptionsRequest)
304 {
305 handleFilterOptionsRequest_(getParentXWindow(),
307 aFilterOptionsRequest,
308 rRequest->getContinuations());
309 return true;
310 }
311 return false;
312}
313
314
315/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
bool handleFilterOptionsRequest(css::uno::Reference< css::task::XInteractionRequest > const &rRequest)
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: iahndl.hxx:74
bool handleNoSuchFilterRequest(css::uno::Reference< css::task::XInteractionRequest > const &rRequest)
const css::uno::Reference< css::awt::XWindow > & getParentXWindow() const
Definition: iahndl.cxx:907
void getContinuations(css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > const &rContinuations, css::uno::Reference< t1 > *pContinuation1, css::uno::Reference< t2 > *pContinuation2)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
FilterNameList::const_iterator FilterNameListPtr
Definition: fltdlg.hxx:36
::std::vector< FilterNamePair > FilterNameList
Definition: fltdlg.hxx:35
OUString sInternal
Definition: fltdlg.hxx:31