Line data Source code
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/XNameContainer.hpp"
23 : #include "com/sun/star/document/AmbigousFilterRequest.hpp"
24 : #include "com/sun/star/document/FilterOptionsRequest.hpp"
25 : #include "com/sun/star/document/NoSuchFilterRequest.hpp"
26 : #include "com/sun/star/document/XImporter.hpp"
27 : #include "com/sun/star/document/XInteractionFilterOptions.hpp"
28 : #include "com/sun/star/document/XInteractionFilterSelect.hpp"
29 : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
30 : #include "com/sun/star/task/XInteractionAbort.hpp"
31 : #include "com/sun/star/task/XInteractionRequest.hpp"
32 : #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
33 :
34 : #include "osl/mutex.hxx"
35 : #include "comphelper/sequenceashashmap.hxx"
36 : #include "vcl/svapp.hxx"
37 :
38 : #include "getcontinuations.hxx"
39 : #include "fltdlg.hxx"
40 :
41 : #include "iahndl.hxx"
42 : #include <boost/scoped_ptr.hpp>
43 :
44 : using namespace com::sun::star;
45 :
46 : namespace {
47 :
48 : void
49 0 : executeFilterDialog(
50 : Window * pParent ,
51 : OUString const & rURL ,
52 : uui::FilterNameList const & rFilters,
53 : OUString & rFilter )
54 : SAL_THROW((uno::RuntimeException))
55 : {
56 : try
57 : {
58 0 : SolarMutexGuard aGuard;
59 :
60 0 : boost::scoped_ptr< ResMgr > xManager(ResMgr::CreateResMgr("uui"));
61 :
62 : boost::scoped_ptr< uui::FilterDialog > xDialog(
63 0 : new uui::FilterDialog(pParent, xManager.get()));
64 :
65 0 : xDialog->SetURL(rURL);
66 0 : xDialog->ChangeFilters(&rFilters);
67 :
68 0 : uui::FilterNameListPtr pSelected = rFilters.end();
69 0 : if( xDialog->AskForFilter( pSelected ) )
70 : {
71 0 : rFilter = pSelected->sInternal;
72 0 : }
73 : }
74 0 : catch (std::bad_alloc const &)
75 : {
76 : throw uno::RuntimeException(
77 : OUString("out of memory"),
78 0 : uno::Reference< uno::XInterface >());
79 : }
80 0 : }
81 :
82 : void
83 0 : handleNoSuchFilterRequest_(
84 : Window * pParent,
85 : uno::Reference< uno::XComponentContext > const & xContext,
86 : document::NoSuchFilterRequest const & rRequest,
87 : uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
88 : rContinuations )
89 : SAL_THROW((uno::RuntimeException))
90 : {
91 0 : uno::Reference< task::XInteractionAbort > xAbort;
92 0 : uno::Reference< document::XInteractionFilterSelect > xFilterTransport;
93 0 : getContinuations(rContinuations, &xAbort, &xFilterTransport);
94 :
95 : // check necessary resources - if they don't exist - abort or
96 : // break this operation
97 0 : if (!xAbort.is())
98 0 : return;
99 :
100 0 : if (!xFilterTransport.is())
101 : {
102 0 : xAbort->select();
103 0 : return;
104 : }
105 :
106 0 : uno::Reference< container::XContainerQuery > xFilterContainer;
107 : try
108 : {
109 0 : xFilterContainer.set( xContext->getServiceManager()->createInstanceWithContext(
110 0 : OUString( "com.sun.star.document.FilterFactory"), xContext ),
111 0 : uno::UNO_QUERY );
112 : }
113 0 : catch ( uno::Exception const & )
114 : {
115 : }
116 :
117 0 : if (!xFilterContainer.is())
118 : {
119 0 : xAbort->select();
120 0 : return;
121 : }
122 :
123 0 : uui::FilterNameList lNames;
124 :
125 : // Note: We look for all filters here which match the following criteria:
126 : // - they are import filters as minimum (of course they can
127 : // support export too)
128 : // - we don't show any filter which are flagged as "don't show it
129 : // at the UI" or "they are not installed"
130 : // - we ignore filters, which have not set any valid
131 : // DocumentService (e.g. our pure graphic filters)
132 : // - we show it sorted by her UIName's
133 : // - We don't use the order flag or prefer default filters.
134 : // (Because this list shows all filters and the user should
135 : // find his filter very easy by his UIName ...)
136 : // - We use "_query_all" here ... but we filter graphic filters
137 : // out by using DocumentService property later!
138 : uno::Reference< container::XEnumeration > xFilters
139 0 : = xFilterContainer->createSubSetEnumerationByQuery(
140 0 : OUString( "_query_all:sort_prop=uiname:iflags=1:eflags=143360"));
141 0 : while (xFilters->hasMoreElements())
142 : {
143 : try
144 : {
145 0 : ::comphelper::SequenceAsHashMap lProps(xFilters->nextElement());
146 0 : uui::FilterNamePair aPair;
147 :
148 0 : aPair.sInternal = lProps.getUnpackedValueOrDefault(
149 0 : OUString("Name"), OUString());
150 0 : aPair.sUI = lProps.getUnpackedValueOrDefault(
151 0 : OUString("UIName"), OUString());
152 0 : if ( aPair.sInternal.isEmpty() || aPair.sUI.isEmpty() )
153 : {
154 0 : continue;
155 : }
156 0 : lNames.push_back( aPair );
157 : }
158 0 : catch(const uno::RuntimeException&)
159 : {
160 0 : throw;
161 : }
162 0 : catch(const uno::Exception&)
163 : {
164 0 : continue;
165 : }
166 : }
167 :
168 : // no list available for showing
169 : // -> abort operation
170 0 : if (lNames.size()<1)
171 : {
172 0 : xAbort->select();
173 0 : return;
174 : }
175 :
176 : // let the user select the right filter
177 0 : OUString sSelectedFilter;
178 : executeFilterDialog( pParent,
179 : rRequest.URL,
180 : lNames,
181 0 : sSelectedFilter );
182 :
183 : // If he doesn't select anyone
184 : // -> abort operation
185 0 : if (sSelectedFilter.isEmpty())
186 : {
187 0 : xAbort->select();
188 0 : return;
189 : }
190 :
191 : // otherwise set it for return
192 0 : xFilterTransport->setFilter( sSelectedFilter );
193 0 : xFilterTransport->select();
194 : }
195 :
196 : void
197 0 : handleAmbigousFilterRequest_(
198 : Window * pParent,
199 : uno::Reference< uno::XComponentContext > const & xContext,
200 : document::AmbigousFilterRequest const & rRequest,
201 : uno::Sequence<
202 : uno::Reference<
203 : task::XInteractionContinuation > > const & rContinuations)
204 : SAL_THROW((uno::RuntimeException))
205 : {
206 0 : uno::Reference< task::XInteractionAbort > xAbort;
207 0 : uno::Reference< document::XInteractionFilterSelect > xFilterTransport;
208 0 : getContinuations(rContinuations, &xAbort, &xFilterTransport);
209 :
210 0 : uui::FilterNameList lNames;
211 :
212 0 : uno::Reference< container::XNameContainer > xFilterContainer;
213 : try
214 : {
215 0 : xFilterContainer.set( xContext->getServiceManager()->createInstanceWithContext(
216 0 : OUString( "com.sun.star.document.FilterFactory"), xContext ),
217 0 : uno::UNO_QUERY );
218 : }
219 0 : catch ( uno::Exception & )
220 : {
221 : }
222 :
223 0 : if( xFilterContainer.is() )
224 : {
225 0 : uno::Any aPackedSet ;
226 0 : uno::Sequence< beans::PropertyValue > lProps ;
227 : sal_Int32 nStep ;
228 0 : uui::FilterNamePair aPair ;
229 :
230 : try
231 : {
232 0 : aPackedSet = xFilterContainer->getByName( rRequest.SelectedFilter );
233 : }
234 0 : catch(const container::NoSuchElementException&)
235 : {
236 0 : aPackedSet.clear();
237 : }
238 0 : aPackedSet >>= lProps;
239 0 : for( nStep=0; nStep<lProps.getLength(); ++nStep )
240 : {
241 0 : if( lProps[nStep].Name.equalsAscii("UIName") )
242 : {
243 0 : OUString sTemp;
244 0 : lProps[nStep].Value >>= sTemp;
245 0 : aPair.sUI = sTemp;
246 0 : aPair.sInternal = rRequest.SelectedFilter;
247 0 : lNames.push_back( aPair );
248 0 : break;
249 : }
250 : }
251 :
252 : try
253 : {
254 0 : aPackedSet = xFilterContainer->getByName( rRequest.DetectedFilter );
255 : }
256 0 : catch(const container::NoSuchElementException&)
257 : {
258 0 : aPackedSet.clear();
259 : }
260 0 : aPackedSet >>= lProps;
261 0 : for( nStep=0; nStep<lProps.getLength(); ++nStep )
262 : {
263 0 : if( lProps[nStep].Name.equalsAscii("UIName") )
264 : {
265 0 : OUString sTemp;
266 0 : lProps[nStep].Value >>= sTemp;
267 0 : aPair.sUI = sTemp;
268 0 : aPair.sInternal = rRequest.DetectedFilter;
269 0 : lNames.push_back( aPair );
270 0 : break;
271 : }
272 0 : }
273 : }
274 :
275 0 : if( xAbort.is() && xFilterTransport.is() )
276 : {
277 0 : if( lNames.size() < 1 )
278 : {
279 0 : xAbort->select();
280 : }
281 : else
282 : {
283 0 : OUString sFilter;
284 : executeFilterDialog( pParent,
285 : rRequest.URL,
286 : lNames,
287 0 : sFilter );
288 :
289 0 : if( !sFilter.isEmpty() )
290 : {
291 0 : xFilterTransport->setFilter( sFilter );
292 0 : xFilterTransport->select();
293 : }
294 : else
295 0 : xAbort->select();
296 : }
297 0 : }
298 0 : }
299 :
300 : void
301 0 : handleFilterOptionsRequest_(
302 : uno::Reference< uno::XComponentContext > const & xContext,
303 : document::FilterOptionsRequest const & rRequest,
304 : uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
305 : rContinuations)
306 : SAL_THROW((uno::RuntimeException))
307 : {
308 0 : uno::Reference< task::XInteractionAbort > xAbort;
309 0 : uno::Reference< document::XInteractionFilterOptions > xFilterOptions;
310 0 : getContinuations(rContinuations, &xAbort, &xFilterOptions);
311 :
312 0 : uno::Reference< container::XNameAccess > xFilterCFG;
313 : try
314 : {
315 0 : xFilterCFG.set( xContext->getServiceManager()->createInstanceWithContext(
316 0 : OUString( "com.sun.star.document.FilterFactory" ), xContext ),
317 0 : uno::UNO_QUERY );
318 : }
319 0 : catch ( uno::Exception const & )
320 : {
321 : }
322 :
323 0 : if( xFilterCFG.is() && rRequest.rProperties.getLength() )
324 : {
325 : try
326 : {
327 0 : OUString aFilterName;
328 0 : sal_Int32 nPropCount = rRequest.rProperties.getLength();
329 0 : for( sal_Int32 ind = 0; ind < nPropCount; ++ind )
330 : {
331 0 : if( rRequest.rProperties[ind].Name.equals(
332 0 : OUString("FilterName")) )
333 : {
334 0 : rRequest.rProperties[ind].Value >>= aFilterName;
335 0 : break;
336 : }
337 : }
338 :
339 0 : uno::Sequence < beans::PropertyValue > aProps;
340 0 : if ( xFilterCFG->getByName( aFilterName ) >>= aProps )
341 : {
342 0 : sal_Int32 nPropertyCount = aProps.getLength();
343 0 : for( sal_Int32 nProperty=0;
344 : nProperty < nPropertyCount;
345 : ++nProperty )
346 0 : if( aProps[nProperty].Name.equals(
347 0 : OUString("UIComponent")) )
348 : {
349 0 : OUString aServiceName;
350 0 : aProps[nProperty].Value >>= aServiceName;
351 0 : if( !aServiceName.isEmpty() )
352 : {
353 : uno::Reference<
354 : ui::dialogs::XExecutableDialog > xFilterDialog(
355 0 : xContext->getServiceManager()->createInstanceWithContext(
356 0 : aServiceName, xContext ),
357 0 : uno::UNO_QUERY );
358 : uno::Reference< beans::XPropertyAccess >
359 : xFilterProperties( xFilterDialog,
360 0 : uno::UNO_QUERY );
361 :
362 0 : if( xFilterDialog.is() && xFilterProperties.is() )
363 : {
364 : uno::Reference<
365 : document::XImporter > xImporter(
366 0 : xFilterDialog, uno::UNO_QUERY );
367 0 : if( xImporter.is() )
368 0 : xImporter->setTargetDocument(
369 : uno::Reference< lang::XComponent >(
370 0 : rRequest.rModel, uno::UNO_QUERY ) );
371 :
372 0 : xFilterProperties->setPropertyValues(
373 0 : rRequest.rProperties );
374 :
375 0 : if( xFilterDialog->execute() )
376 : {
377 0 : xFilterOptions->setFilterOptions(
378 0 : xFilterProperties->getPropertyValues() );
379 0 : xFilterOptions->select();
380 0 : return;
381 0 : }
382 0 : }
383 : }
384 0 : break;
385 : }
386 0 : }
387 : }
388 0 : catch( container::NoSuchElementException& )
389 : {
390 : // the filter name is unknown
391 : }
392 0 : catch( uno::Exception& )
393 : {
394 : }
395 : }
396 :
397 0 : xAbort->select();
398 : }
399 :
400 : } // namespace
401 :
402 : bool
403 0 : UUIInteractionHelper::handleNoSuchFilterRequest(
404 : uno::Reference< task::XInteractionRequest > const & rRequest)
405 : SAL_THROW((uno::RuntimeException))
406 : {
407 0 : uno::Any aAnyRequest(rRequest->getRequest());
408 :
409 0 : document::NoSuchFilterRequest aNoSuchFilterRequest;
410 0 : if (aAnyRequest >>= aNoSuchFilterRequest)
411 : {
412 : handleNoSuchFilterRequest_(getParentProperty(),
413 : m_xContext,
414 : aNoSuchFilterRequest,
415 0 : rRequest->getContinuations());
416 0 : return true;
417 : }
418 0 : return false;
419 : }
420 :
421 : bool
422 0 : UUIInteractionHelper::handleAmbigousFilterRequest(
423 : uno::Reference< task::XInteractionRequest > const & rRequest)
424 : SAL_THROW((uno::RuntimeException))
425 : {
426 0 : uno::Any aAnyRequest(rRequest->getRequest());
427 :
428 0 : document::AmbigousFilterRequest aAmbigousFilterRequest;
429 0 : if (aAnyRequest >>= aAmbigousFilterRequest)
430 : {
431 : handleAmbigousFilterRequest_(getParentProperty(),
432 : m_xContext,
433 : aAmbigousFilterRequest,
434 0 : rRequest->getContinuations());
435 0 : return true;
436 : }
437 0 : return false;
438 : }
439 :
440 : bool
441 0 : UUIInteractionHelper::handleFilterOptionsRequest(
442 : uno::Reference< task::XInteractionRequest > const & rRequest)
443 : SAL_THROW((uno::RuntimeException))
444 : {
445 0 : uno::Any aAnyRequest(rRequest->getRequest());
446 :
447 0 : document::FilterOptionsRequest aFilterOptionsRequest;
448 0 : if (aAnyRequest >>= aFilterOptionsRequest)
449 : {
450 : handleFilterOptionsRequest_(m_xContext,
451 : aFilterOptionsRequest,
452 0 : rRequest->getContinuations());
453 0 : return true;
454 : }
455 0 : return false;
456 : }
457 :
458 :
459 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|