xref: /aoo4110/main/uui/source/iahndl-filter.cxx (revision b1cdbd2c)
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