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