Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / uui / source / iahndl-filter.cxx
blob067d7035a8e6d7006038e5146ede9b1dcf5c2278
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
34 #include "osl/mutex.hxx"
35 #include "comphelper/sequenceashashmap.hxx"
36 #include "vcl/svapp.hxx"
38 #include "getcontinuations.hxx"
39 #include "fltdlg.hxx"
41 #include "iahndl.hxx"
43 using namespace com::sun::star;
45 namespace {
47 void
48 executeFilterDialog(
49 Window * pParent ,
50 rtl::OUString const & rURL ,
51 uui::FilterNameList const & rFilters,
52 rtl::OUString & rFilter )
53 SAL_THROW((uno::RuntimeException))
55 try
57 SolarMutexGuard aGuard;
59 std::auto_ptr< ResMgr > xManager(ResMgr::CreateResMgr("uui"));
61 std::auto_ptr< uui::FilterDialog > xDialog(
62 new uui::FilterDialog(pParent, xManager.get()));
64 xDialog->SetURL(rURL);
65 xDialog->ChangeFilters(&rFilters);
67 uui::FilterNameListPtr pSelected = rFilters.end();
68 if( xDialog->AskForFilter( pSelected ) )
70 rFilter = pSelected->sInternal;
73 catch (std::bad_alloc const &)
75 throw uno::RuntimeException(
76 rtl::OUString("out of memory"),
77 uno::Reference< uno::XInterface >());
81 void
82 handleNoSuchFilterRequest_(
83 Window * pParent,
84 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory,
85 document::NoSuchFilterRequest const & rRequest,
86 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
87 rContinuations )
88 SAL_THROW((uno::RuntimeException))
90 uno::Reference< task::XInteractionAbort > xAbort;
91 uno::Reference< document::XInteractionFilterSelect > xFilterTransport;
92 getContinuations(rContinuations, &xAbort, &xFilterTransport);
94 // check neccessary resources - if they don't exist - abort or
95 // break this operation
96 if (!xAbort.is())
97 return;
99 if (!xFilterTransport.is())
101 xAbort->select();
102 return;
105 uno::Reference< container::XContainerQuery > xFilterContainer;
108 xFilterContainer.set( xServiceFactory->createInstance(
109 ::rtl::OUString( "com.sun.star.document.FilterFactory") ),
110 uno::UNO_QUERY );
112 catch ( uno::Exception const & )
116 if (!xFilterContainer.is())
118 xAbort->select();
119 return;
122 uui::FilterNameList lNames;
124 // Note: We look for all filters here which match the following criteria:
125 // - they are import filters as minimum (of course they can
126 // support export too)
127 // - we don't show any filter which are flagged as "don't show it
128 // at the UI" or "they are not installed"
129 // - we ignore filters, which have not set any valid
130 // DocumentService (e.g. our pure graphic filters)
131 // - we show it sorted by her UIName's
132 // - We don't use the order flag or prefer default filters.
133 // (Because this list shows all filters and the user should
134 // find his filter very easy by his UIName ...)
135 // - We use "_query_all" here ... but we filter graphic filters
136 // out by using DocumentService property later!
137 uno::Reference< container::XEnumeration > xFilters
138 = xFilterContainer->createSubSetEnumerationByQuery(
139 ::rtl::OUString( "_query_all:sort_prop=uiname:iflags=1:eflags=143360"));
140 while (xFilters->hasMoreElements())
144 ::comphelper::SequenceAsHashMap lProps(xFilters->nextElement());
145 uui::FilterNamePair aPair;
147 aPair.sInternal = lProps.getUnpackedValueOrDefault(
148 rtl::OUString("Name"), ::rtl::OUString());
149 aPair.sUI = lProps.getUnpackedValueOrDefault(
150 rtl::OUString("UIName"), ::rtl::OUString());
151 if ( (!aPair.sInternal.Len()) || (!aPair.sUI.Len() ) )
153 continue;
155 lNames.push_back( aPair );
157 catch(const uno::RuntimeException&)
159 throw;
161 catch(const uno::Exception&)
163 continue;
167 // no list available for showing
168 // -> abort operation
169 if (lNames.size()<1)
171 xAbort->select();
172 return;
175 // let the user select the right filter
176 rtl::OUString sSelectedFilter;
177 executeFilterDialog( pParent,
178 rRequest.URL,
179 lNames,
180 sSelectedFilter );
182 // If he doesn't select anyone
183 // -> abort operation
184 if (sSelectedFilter.isEmpty())
186 xAbort->select();
187 return;
190 // otherwise set it for return
191 xFilterTransport->setFilter( sSelectedFilter );
192 xFilterTransport->select();
195 void
196 handleAmbigousFilterRequest_(
197 Window * pParent,
198 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory,
199 document::AmbigousFilterRequest const & rRequest,
200 uno::Sequence<
201 uno::Reference<
202 task::XInteractionContinuation > > const & rContinuations)
203 SAL_THROW((uno::RuntimeException))
205 uno::Reference< task::XInteractionAbort > xAbort;
206 uno::Reference< document::XInteractionFilterSelect > xFilterTransport;
207 getContinuations(rContinuations, &xAbort, &xFilterTransport);
209 uui::FilterNameList lNames;
211 uno::Reference< container::XNameContainer > xFilterContainer;
214 xFilterContainer.set( xServiceFactory->createInstance(
215 ::rtl::OUString( "com.sun.star.document.FilterFactory") ),
216 uno::UNO_QUERY );
218 catch ( uno::Exception & )
222 if( xFilterContainer.is() )
224 uno::Any aPackedSet ;
225 uno::Sequence< beans::PropertyValue > lProps ;
226 sal_Int32 nStep ;
227 uui::FilterNamePair aPair ;
231 aPackedSet = xFilterContainer->getByName( rRequest.SelectedFilter );
233 catch(const container::NoSuchElementException&)
235 aPackedSet.clear();
237 aPackedSet >>= lProps;
238 for( nStep=0; nStep<lProps.getLength(); ++nStep )
240 if( lProps[nStep].Name.compareToAscii("UIName") == 0 )
242 ::rtl::OUString sTemp;
243 lProps[nStep].Value >>= sTemp;
244 aPair.sUI = sTemp;
245 aPair.sInternal = rRequest.SelectedFilter;
246 lNames.push_back( aPair );
247 break;
253 aPackedSet = xFilterContainer->getByName( rRequest.DetectedFilter );
255 catch(const container::NoSuchElementException&)
257 aPackedSet.clear();
259 aPackedSet >>= lProps;
260 for( nStep=0; nStep<lProps.getLength(); ++nStep )
262 if( lProps[nStep].Name.compareToAscii("UIName") == 0 )
264 ::rtl::OUString sTemp;
265 lProps[nStep].Value >>= sTemp;
266 aPair.sUI = sTemp;
267 aPair.sInternal = rRequest.DetectedFilter;
268 lNames.push_back( aPair );
269 break;
274 if( xAbort.is() && xFilterTransport.is() )
276 if( lNames.size() < 1 )
278 xAbort->select();
280 else
282 rtl::OUString sFilter;
283 executeFilterDialog( pParent,
284 rRequest.URL,
285 lNames,
286 sFilter );
288 if( !sFilter.isEmpty() )
290 xFilterTransport->setFilter( sFilter );
291 xFilterTransport->select();
293 else
294 xAbort->select();
299 void
300 handleFilterOptionsRequest_(
301 uno::Reference< lang::XMultiServiceFactory > const & xServiceFactory,
302 document::FilterOptionsRequest const & rRequest,
303 uno::Sequence< uno::Reference< task::XInteractionContinuation > > const &
304 rContinuations)
305 SAL_THROW((uno::RuntimeException))
307 uno::Reference< task::XInteractionAbort > xAbort;
308 uno::Reference< document::XInteractionFilterOptions > xFilterOptions;
309 getContinuations(rContinuations, &xAbort, &xFilterOptions);
311 uno::Reference< container::XNameAccess > xFilterCFG;
314 xFilterCFG.set( xServiceFactory->createInstance(
315 ::rtl::OUString( "com.sun.star.document.FilterFactory" ) ),
316 uno::UNO_QUERY );
318 catch ( uno::Exception const & )
322 if( xFilterCFG.is() && rRequest.rProperties.getLength() )
326 ::rtl::OUString aFilterName;
327 sal_Int32 nPropCount = rRequest.rProperties.getLength();
328 for( sal_Int32 ind = 0; ind < nPropCount; ++ind )
330 if( rRequest.rProperties[ind].Name.equals(
331 ::rtl::OUString("FilterName")) )
333 rRequest.rProperties[ind].Value >>= aFilterName;
334 break;
338 uno::Sequence < beans::PropertyValue > aProps;
339 if ( xFilterCFG->getByName( aFilterName ) >>= aProps )
341 sal_Int32 nPropertyCount = aProps.getLength();
342 for( sal_Int32 nProperty=0;
343 nProperty < nPropertyCount;
344 ++nProperty )
345 if( aProps[nProperty].Name.equals(
346 ::rtl::OUString("UIComponent")) )
348 ::rtl::OUString aServiceName;
349 aProps[nProperty].Value >>= aServiceName;
350 if( !aServiceName.isEmpty() )
352 uno::Reference<
353 ui::dialogs::XExecutableDialog > xFilterDialog(
354 xServiceFactory->createInstance(
355 aServiceName ),
356 uno::UNO_QUERY );
357 uno::Reference< beans::XPropertyAccess >
358 xFilterProperties( xFilterDialog,
359 uno::UNO_QUERY );
361 if( xFilterDialog.is() && xFilterProperties.is() )
363 uno::Reference<
364 document::XImporter > xImporter(
365 xFilterDialog, uno::UNO_QUERY );
366 if( xImporter.is() )
367 xImporter->setTargetDocument(
368 uno::Reference< lang::XComponent >(
369 rRequest.rModel, uno::UNO_QUERY ) );
371 xFilterProperties->setPropertyValues(
372 rRequest.rProperties );
374 if( xFilterDialog->execute() )
376 xFilterOptions->setFilterOptions(
377 xFilterProperties->getPropertyValues() );
378 xFilterOptions->select();
379 return;
383 break;
387 catch( container::NoSuchElementException& )
389 // the filter name is unknown
391 catch( uno::Exception& )
396 xAbort->select();
399 } // namespace
401 bool
402 UUIInteractionHelper::handleNoSuchFilterRequest(
403 uno::Reference< task::XInteractionRequest > const & rRequest)
404 SAL_THROW((uno::RuntimeException))
406 uno::Any aAnyRequest(rRequest->getRequest());
408 document::NoSuchFilterRequest aNoSuchFilterRequest;
409 if (aAnyRequest >>= aNoSuchFilterRequest)
411 handleNoSuchFilterRequest_(getParentProperty(),
412 m_xServiceFactory,
413 aNoSuchFilterRequest,
414 rRequest->getContinuations());
415 return true;
417 return false;
420 bool
421 UUIInteractionHelper::handleAmbigousFilterRequest(
422 uno::Reference< task::XInteractionRequest > const & rRequest)
423 SAL_THROW((uno::RuntimeException))
425 uno::Any aAnyRequest(rRequest->getRequest());
427 document::AmbigousFilterRequest aAmbigousFilterRequest;
428 if (aAnyRequest >>= aAmbigousFilterRequest)
430 handleAmbigousFilterRequest_(getParentProperty(),
431 m_xServiceFactory,
432 aAmbigousFilterRequest,
433 rRequest->getContinuations());
434 return true;
436 return false;
439 bool
440 UUIInteractionHelper::handleFilterOptionsRequest(
441 uno::Reference< task::XInteractionRequest > const & rRequest)
442 SAL_THROW((uno::RuntimeException))
444 uno::Any aAnyRequest(rRequest->getRequest());
446 document::FilterOptionsRequest aFilterOptionsRequest;
447 if (aAnyRequest >>= aFilterOptionsRequest)
449 handleFilterOptionsRequest_(m_xServiceFactory,
450 aFilterOptionsRequest,
451 rRequest->getContinuations());
452 return true;
454 return false;
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */