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