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