Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <com/sun/star/uno/Exception.hpp>
22 : #include <com/sun/star/beans/PropertyValue.hpp>
23 : #include <com/sun/star/beans/NamedValue.hpp>
24 : #include <com/sun/star/container/XNameAccess.hpp>
25 : #include <com/sun/star/container/XEnumeration.hpp>
26 : #include <com/sun/star/datatransfer/DataFlavor.hpp>
27 : #include <com/sun/star/document/XTypeDetection.hpp>
28 : #include <com/sun/star/container/XContainerQuery.hpp>
29 :
30 : #include <comphelper/sequenceashashmap.hxx>
31 :
32 : #include <sot/exchange.hxx>
33 : #include <basic/sbmeth.hxx>
34 : #include <basic/basmgr.hxx>
35 : #include <basic/sbstar.hxx>
36 : #include <basic/sbxobj.hxx>
37 : #include <basic/sbxmeth.hxx>
38 : #include <basic/sbxcore.hxx>
39 : #include <vcl/msgbox.hxx>
40 : #include <rtl/ustring.hxx>
41 : #include <rtl/ustrbuf.hxx>
42 : #include <svl/eitem.hxx>
43 : #include <svl/intitem.hxx>
44 : #include <svl/stritem.hxx>
45 : #include <svl/lckbitem.hxx>
46 : #include <svl/inettype.hxx>
47 : #include <svl/rectitem.hxx>
48 :
49 : #include <sot/storage.hxx>
50 : #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
51 : #include <com/sun/star/frame/XDispatch.hpp>
52 : #include <com/sun/star/frame/XDispatchProvider.hpp>
53 : #include <com/sun/star/frame/XStatusListener.hpp>
54 : #include <com/sun/star/frame/FrameSearchFlag.hpp>
55 : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
56 : #include <com/sun/star/frame/FeatureStateEvent.hpp>
57 : #include <com/sun/star/frame/DispatchDescriptor.hpp>
58 : #include <com/sun/star/frame/XController.hpp>
59 : #include <com/sun/star/frame/XFrameActionListener.hpp>
60 : #include <com/sun/star/frame/XComponentLoader.hpp>
61 : #include <com/sun/star/frame/XFrame.hpp>
62 : #include <com/sun/star/frame/FrameActionEvent.hpp>
63 : #include <com/sun/star/frame/FrameAction.hpp>
64 : #include <com/sun/star/frame/XFrameLoader.hpp>
65 : #include <com/sun/star/frame/XLoadEventListener.hpp>
66 : #include <com/sun/star/frame/XFilterDetect.hpp>
67 : #include <com/sun/star/loader/XImplementationLoader.hpp>
68 : #include <comphelper/processfactory.hxx>
69 :
70 : #include <sal/types.h>
71 : #include <com/sun/star/uno/Reference.hxx>
72 : #include <com/sun/star/ucb/XContent.hpp>
73 : #include <unotools/pathoptions.hxx>
74 : #include <unotools/moduleoptions.hxx>
75 : #include <unotools/mediadescriptor.hxx>
76 : #include <tools/urlobj.hxx>
77 :
78 : #include <rtl/instance.hxx>
79 :
80 : #include <svl/ctypeitm.hxx>
81 : #include <svtools/sfxecode.hxx>
82 : #include <unotools/syslocale.hxx>
83 :
84 : #include <sfx2/sfxhelp.hxx>
85 : #include <sfx2/docfilt.hxx>
86 : #include <sfx2/docfac.hxx>
87 : #include "sfxtypes.hxx"
88 : #include <sfx2/sfxuno.hxx>
89 : #include <sfx2/docfile.hxx>
90 : #include <sfx2/progress.hxx>
91 : #include "openflag.hxx"
92 : #include "bastyp.hrc"
93 : #include <sfx2/sfxresid.hxx>
94 : #include <sfx2/doctempl.hxx>
95 : #include <sfx2/frame.hxx>
96 : #include <sfx2/dispatch.hxx>
97 : #include <sfx2/viewfrm.hxx>
98 : #include "helper.hxx"
99 : #include "fltlst.hxx"
100 : #include <sfx2/request.hxx>
101 : #include "arrdecl.hxx"
102 :
103 : #include <boost/ptr_container/ptr_vector.hpp>
104 : #include <functional>
105 :
106 : #if defined(DBG_UTIL)
107 : unsigned SfxStack::nLevel = 0;
108 : #endif
109 :
110 : using namespace com::sun::star;
111 :
112 : namespace
113 : {
114 : class theSfxFilterListener : public rtl::Static<SfxFilterListener, theSfxFilterListener> {};
115 : class theSfxFilterArray : public rtl::Static<SfxFilterList_Impl, theSfxFilterArray > {};
116 : }
117 :
118 : static SfxFilterList_Impl* pFilterArr = 0;
119 : static bool bFirstRead = true;
120 :
121 0 : static void CreateFilterArr()
122 : {
123 0 : pFilterArr = &theSfxFilterArray::get();
124 0 : theSfxFilterListener::get();
125 0 : }
126 :
127 :
128 0 : inline OUString ToUpper_Impl( const OUString &rStr )
129 : {
130 0 : return SvtSysLocale().GetCharClass().uppercase( rStr );
131 : }
132 :
133 :
134 0 : class SfxFilterContainer_Impl
135 : {
136 : public:
137 : OUString aName;
138 : OUString aServiceName;
139 :
140 0 : SfxFilterContainer_Impl( const OUString& rName )
141 0 : : aName( rName )
142 : {
143 0 : aServiceName = SfxObjectShell::GetServiceNameFromFactory( rName );
144 0 : }
145 : };
146 :
147 : #define IMPL_FORWARD_LOOP( aMethod, ArgType, aArg ) \
148 : const SfxFilter* SfxFilterContainer::aMethod( ArgType aArg, SfxFilterFlags nMust, SfxFilterFlags nDont ) const \
149 : {\
150 : SfxFilterMatcher aMatch( pImpl->aName ); \
151 : return aMatch.aMethod( aArg, nMust, nDont ); \
152 : }
153 :
154 0 : IMPL_FORWARD_LOOP( GetFilter4EA, const OUString&, rEA );
155 0 : IMPL_FORWARD_LOOP( GetFilter4Extension, const OUString&, rExt );
156 0 : IMPL_FORWARD_LOOP( GetFilter4FilterName, const OUString&, rName );
157 :
158 0 : const SfxFilter* SfxFilterContainer::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
159 : {
160 0 : SfxFilterMatcher aMatch( pImpl->aName );
161 0 : return aMatch.GetAnyFilter( nMust, nDont );
162 : }
163 :
164 :
165 :
166 0 : SfxFilterContainer::SfxFilterContainer( const OUString& rName )
167 : {
168 0 : pImpl = new SfxFilterContainer_Impl( rName );
169 0 : }
170 :
171 :
172 :
173 0 : SfxFilterContainer::~SfxFilterContainer()
174 : {
175 0 : delete pImpl;
176 0 : }
177 :
178 :
179 :
180 0 : const OUString SfxFilterContainer::GetName() const
181 : {
182 0 : return pImpl->aName;
183 : }
184 :
185 0 : const SfxFilter* SfxFilterContainer::GetDefaultFilter_Impl( const OUString& rName )
186 : {
187 : // Try to find out the type of factory.
188 : // Interpret given name as Service- and ShortName!
189 0 : SvtModuleOptions aOpt;
190 0 : SvtModuleOptions::EFactory eFactory = aOpt.ClassifyFactoryByServiceName(rName);
191 0 : if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
192 0 : eFactory = aOpt.ClassifyFactoryByShortName(rName);
193 :
194 : // could not classify factory by its service nor by its short name.
195 : // Must be an unknown factory! => return NULL
196 0 : if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
197 0 : return NULL;
198 :
199 : // For the following code we need some additional information.
200 0 : OUString sServiceName = aOpt.GetFactoryName(eFactory);
201 0 : OUString sDefaultFilter = aOpt.GetFactoryDefaultFilter(eFactory);
202 :
203 : // Try to get the default filter. Dont fiorget to verify it.
204 : // May the set default filter does not exists any longer or
205 : // does not fit the given factory.
206 0 : const SfxFilterMatcher aMatcher;
207 0 : const SfxFilter* pFilter = aMatcher.GetFilter4FilterName(sDefaultFilter);
208 :
209 0 : if (
210 0 : pFilter &&
211 0 : !pFilter->GetServiceName().equalsIgnoreAsciiCase(sServiceName)
212 : )
213 : {
214 0 : pFilter = 0;
215 : }
216 :
217 : // If at least no default filter could be located - use any filter of this
218 : // factory.
219 0 : if (!pFilter)
220 : {
221 0 : if ( bFirstRead )
222 0 : ReadFilters_Impl();
223 :
224 0 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
225 : {
226 0 : const SfxFilter* pCheckFilter = (*pFilterArr)[i];
227 0 : if ( pCheckFilter->GetServiceName().equalsIgnoreAsciiCase(sServiceName) )
228 : {
229 0 : pFilter = pCheckFilter;
230 0 : break;
231 : }
232 : }
233 : }
234 :
235 0 : return pFilter;
236 : }
237 :
238 :
239 :
240 :
241 : // Impl-Data is shared between all FilterMatchers of the same factory
242 : class SfxFilterMatcher_Impl
243 : {
244 : public:
245 : OUString aName;
246 : mutable SfxFilterList_Impl* pList; // is created on demand
247 :
248 : void InitForIterating() const;
249 : void Update() const;
250 0 : SfxFilterMatcher_Impl(const OUString &rName)
251 : : aName(rName)
252 0 : , pList(0)
253 : {
254 0 : }
255 0 : ~SfxFilterMatcher_Impl()
256 0 : {
257 : // SfxFilterMatcher_Impl::InitForIterating() will set pList to
258 : // either the global filter array matcher pFilterArr, or to
259 : // a new SfxFilterList_Impl.
260 0 : if (pList != pFilterArr)
261 0 : delete pList;
262 0 : }
263 : };
264 :
265 : namespace
266 : {
267 : typedef boost::ptr_vector<SfxFilterMatcher_Impl> SfxFilterMatcherArr_Impl;
268 1 : static SfxFilterMatcherArr_Impl aImplArr;
269 : static int nSfxFilterMatcherCount;
270 :
271 : class hasName :
272 : public std::unary_function<SfxFilterMatcher_Impl, bool>
273 : {
274 : private:
275 : const OUString& mrName;
276 : public:
277 0 : hasName(const OUString &rName) : mrName(rName) {}
278 0 : bool operator() (const SfxFilterMatcher_Impl& rImpl) const
279 : {
280 0 : return rImpl.aName == mrName;
281 : }
282 : };
283 :
284 0 : SfxFilterMatcher_Impl & getSfxFilterMatcher_Impl(const OUString &rName)
285 : {
286 0 : OUString aName;
287 :
288 0 : if (!rName.isEmpty())
289 0 : aName = SfxObjectShell::GetServiceNameFromFactory(rName);
290 :
291 : // find the impl-Data of any comparable FilterMatcher that was created
292 : // previously
293 0 : SfxFilterMatcherArr_Impl::iterator aEnd = aImplArr.end();
294 : SfxFilterMatcherArr_Impl::iterator aIter =
295 0 : std::find_if(aImplArr.begin(), aEnd, hasName(aName));
296 0 : if (aIter != aEnd)
297 0 : return *aIter;
298 :
299 : // first Matcher created for this factory
300 0 : SfxFilterMatcher_Impl *pImpl = new SfxFilterMatcher_Impl(aName);
301 0 : aImplArr.push_back(pImpl);
302 0 : return *pImpl;
303 : }
304 : }
305 :
306 0 : SfxFilterMatcher::SfxFilterMatcher( const OUString& rName )
307 0 : : m_rImpl( getSfxFilterMatcher_Impl(rName) )
308 : {
309 0 : ++nSfxFilterMatcherCount;
310 0 : }
311 :
312 0 : SfxFilterMatcher::SfxFilterMatcher()
313 0 : : m_rImpl( getSfxFilterMatcher_Impl(OUString()) )
314 : {
315 : // global FilterMatcher always uses global filter array (also created on
316 : // demand)
317 0 : ++nSfxFilterMatcherCount;
318 0 : }
319 :
320 0 : SfxFilterMatcher::~SfxFilterMatcher()
321 : {
322 0 : --nSfxFilterMatcherCount;
323 0 : if (nSfxFilterMatcherCount == 0)
324 0 : aImplArr.clear();
325 0 : }
326 :
327 0 : void SfxFilterMatcher_Impl::Update() const
328 : {
329 0 : if ( pList )
330 : {
331 : // this List was already used
332 0 : pList->clear();
333 0 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
334 : {
335 0 : SfxFilter* pFilter = (*pFilterArr)[i];
336 0 : if ( pFilter->GetServiceName() == aName )
337 0 : pList->push_back( pFilter );
338 : }
339 : }
340 0 : }
341 :
342 0 : void SfxFilterMatcher_Impl::InitForIterating() const
343 : {
344 0 : if ( pList )
345 0 : return;
346 :
347 0 : if ( bFirstRead )
348 : // global filter array has not been created yet
349 0 : SfxFilterContainer::ReadFilters_Impl();
350 :
351 0 : if ( !aName.isEmpty() )
352 : {
353 : // matcher of factory: use only filters of that document type
354 0 : pList = new SfxFilterList_Impl;
355 0 : Update();
356 : }
357 : else
358 : {
359 : // global matcher: use global filter array
360 0 : pList = pFilterArr;
361 : }
362 : }
363 :
364 0 : const SfxFilter* SfxFilterMatcher::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
365 : {
366 0 : m_rImpl.InitForIterating();
367 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
368 : {
369 0 : const SfxFilter* pFilter = (*m_rImpl.pList)[i];
370 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
371 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
372 0 : return pFilter;
373 : }
374 :
375 0 : return NULL;
376 : }
377 :
378 :
379 :
380 0 : sal_uInt32 SfxFilterMatcher::GuessFilterIgnoringContent(
381 : SfxMedium& rMedium,
382 : const SfxFilter**ppFilter,
383 : SfxFilterFlags nMust,
384 : SfxFilterFlags nDont ) const
385 : {
386 : uno::Reference<document::XTypeDetection> xDetection(
387 0 : comphelper::getProcessServiceFactory()->createInstance("com.sun.star.document.TypeDetection"), uno::UNO_QUERY);
388 :
389 0 : OUString sTypeName;
390 : try
391 : {
392 0 : sTypeName = xDetection->queryTypeByURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
393 : }
394 0 : catch (uno::Exception&)
395 : {
396 : }
397 :
398 0 : *ppFilter = NULL;
399 0 : if ( !sTypeName.isEmpty() )
400 : {
401 : // make sure filter list is initialized
402 0 : m_rImpl.InitForIterating();
403 0 : *ppFilter = GetFilter4EA( sTypeName, nMust, nDont );
404 : }
405 :
406 0 : return *ppFilter ? ERRCODE_NONE : ERRCODE_ABORT;
407 : }
408 :
409 :
410 :
411 0 : sal_uInt32 SfxFilterMatcher::GuessFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
412 : {
413 0 : return GuessFilterControlDefaultUI( rMedium, ppFilter, nMust, nDont, true );
414 : }
415 :
416 :
417 :
418 0 : sal_uInt32 SfxFilterMatcher::GuessFilterControlDefaultUI( SfxMedium& rMedium, const SfxFilter** ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont, bool /*bDefUI*/ ) const
419 : {
420 0 : const SfxFilter* pOldFilter = *ppFilter;
421 :
422 : // no detection service -> nothing to do !
423 : uno::Reference<document::XTypeDetection> xDetection(
424 0 : comphelper::getProcessServiceFactory()->createInstance("com.sun.star.document.TypeDetection"), uno::UNO_QUERY);
425 :
426 0 : if (!xDetection.is())
427 0 : return ERRCODE_ABORT;
428 :
429 0 : OUString sTypeName;
430 : try
431 : {
432 : // open the stream one times only ...
433 : // Otherwhise it will be tried more then once and show the same interaction more then once ...
434 :
435 0 : OUString sURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
436 0 : uno::Reference< io::XInputStream > xInStream = rMedium.GetInputStream();
437 0 : OUString aFilterName;
438 :
439 : // stream exists => deep detection (with preselection ... if possible)
440 0 : if (xInStream.is())
441 : {
442 0 : utl::MediaDescriptor aDescriptor;
443 :
444 0 : aDescriptor[utl::MediaDescriptor::PROP_URL() ] <<= sURL;
445 0 : aDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM() ] <<= xInStream;
446 0 : aDescriptor[utl::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= rMedium.GetInteractionHandler();
447 : SfxStringItem const * it = static_cast<SfxStringItem const *>(
448 0 : rMedium.GetItemSet()->GetItem(SID_REFERER));
449 0 : if (it != 0) {
450 0 : aDescriptor[utl::MediaDescriptor::PROP_REFERRER()]
451 0 : <<= it->GetValue();
452 : }
453 :
454 0 : if ( !m_rImpl.aName.isEmpty() )
455 0 : aDescriptor[utl::MediaDescriptor::PROP_DOCUMENTSERVICE()] <<= m_rImpl.aName;
456 :
457 0 : if ( pOldFilter )
458 : {
459 0 : aDescriptor[utl::MediaDescriptor::PROP_TYPENAME() ] <<= OUString( pOldFilter->GetTypeName() );
460 0 : aDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] <<= OUString( pOldFilter->GetFilterName() );
461 : }
462 :
463 0 : uno::Sequence< beans::PropertyValue > lDescriptor = aDescriptor.getAsConstPropertyValueList();
464 0 : sTypeName = xDetection->queryTypeByDescriptor(lDescriptor, sal_True); // lDescriptor is used as In/Out param ... dont use aDescriptor.getAsConstPropertyValueList() directly!
465 :
466 0 : for (sal_Int32 i = 0; i < lDescriptor.getLength(); ++i)
467 : {
468 0 : if (lDescriptor[i].Name == "FilterName")
469 : // Type detection picked a preferred filter for this format.
470 0 : aFilterName = lDescriptor[i].Value.get<OUString>();
471 0 : }
472 : }
473 : // no stream exists => try flat detection without preselection as fallback
474 : else
475 0 : sTypeName = xDetection->queryTypeByURL(sURL);
476 :
477 0 : if (!sTypeName.isEmpty())
478 : {
479 0 : const SfxFilter* pFilter = NULL;
480 0 : if (!aFilterName.isEmpty())
481 : // Type detection returned a suitable filter for this. Use it.
482 0 : pFilter = SfxFilter::GetFilterByName(aFilterName);
483 :
484 0 : if (!pFilter)
485 : {
486 : // detect filter by given type
487 : // In case of this matcher is bound to a particular document type:
488 : // If there is no acceptable type for this document at all, the type detection has possibly returned something else.
489 : // The DocumentService property is only a preselection, and all preselections are considered as optional!
490 : // This "wrong" type will be sorted out now because we match only allowed filters to the detected type
491 0 : uno::Sequence< beans::NamedValue > lQuery(1);
492 0 : lQuery[0].Name = "Name";
493 0 : lQuery[0].Value <<= sTypeName;
494 :
495 0 : pFilter = GetFilterForProps(lQuery, nMust, nDont);
496 : }
497 :
498 0 : if (pFilter)
499 : {
500 0 : *ppFilter = pFilter;
501 0 : return ERRCODE_NONE;
502 : }
503 0 : }
504 : }
505 0 : catch (const uno::Exception&)
506 : {}
507 :
508 0 : return ERRCODE_ABORT;
509 : }
510 :
511 :
512 0 : bool SfxFilterMatcher::IsFilterInstalled_Impl( const SfxFilter* pFilter )
513 : {
514 0 : if ( pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL )
515 : {
516 : // Here could a re-installation be offered
517 0 : OUString aText( SfxResId(STR_FILTER_NOT_INSTALLED).toString() );
518 0 : aText = aText.replaceFirst( "$(FILTER)", pFilter->GetUIName() );
519 0 : QueryBox aQuery( NULL, WB_YES_NO | WB_DEF_YES, aText );
520 0 : short nRet = aQuery.Execute();
521 : if ( nRet == RET_YES )
522 : {
523 : #ifdef DBG_UTIL
524 : // Start Setup
525 : InfoBox( NULL, "Here should the Setup now be starting!" ).Execute();
526 : #endif
527 : // Installation must still give feedback if it worked or not,
528 : // then the Filterflag be deleted
529 : }
530 :
531 0 : return ( !(pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL) );
532 : }
533 0 : else if ( pFilter->GetFilterFlags() & SFX_FILTER_CONSULTSERVICE )
534 : {
535 0 : OUString aText( SfxResId(STR_FILTER_CONSULT_SERVICE).toString() );
536 0 : aText = aText.replaceFirst( "$(FILTER)", pFilter->GetUIName() );
537 0 : InfoBox ( NULL, aText ).Execute();
538 0 : return false;
539 : }
540 : else
541 0 : return true;
542 : }
543 :
544 :
545 0 : sal_uInt32 SfxFilterMatcher::DetectFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, bool /*bPlugIn*/, bool bAPI ) const
546 : /* [Description]
547 :
548 : Here the Filter selection box is pulled up. Otherwise GuessFilter
549 : */
550 :
551 : {
552 0 : const SfxFilter* pOldFilter = rMedium.GetFilter();
553 0 : if ( pOldFilter )
554 : {
555 0 : if( !IsFilterInstalled_Impl( pOldFilter ) )
556 0 : pOldFilter = 0;
557 : else
558 : {
559 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, false);
560 0 : if ( ( pOldFilter->GetFilterFlags() & SFX_FILTER_PACKED ) && pSalvageItem )
561 : // Salvage is always done without packing
562 0 : pOldFilter = 0;
563 : }
564 : }
565 :
566 0 : const SfxFilter* pFilter = pOldFilter;
567 :
568 0 : bool bPreview = rMedium.IsPreview_Impl();
569 0 : SFX_ITEMSET_ARG(rMedium.GetItemSet(), pReferer, SfxStringItem, SID_REFERER, false);
570 0 : if ( bPreview && rMedium.IsRemote() && ( !pReferer || !pReferer->GetValue().match("private:searchfolder:") ) )
571 0 : return ERRCODE_ABORT;
572 :
573 0 : ErrCode nErr = GuessFilter( rMedium, &pFilter );
574 0 : if ( nErr == ERRCODE_ABORT )
575 0 : return nErr;
576 :
577 0 : if ( nErr == ERRCODE_IO_PENDING )
578 : {
579 0 : *ppFilter = pFilter;
580 0 : return nErr;
581 : }
582 :
583 0 : if ( !pFilter )
584 : {
585 0 : const SfxFilter* pInstallFilter = NULL;
586 :
587 : // Now test the filter which are not installed (ErrCode is irrelevant)
588 0 : GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, SFX_FILTER_CONSULTSERVICE );
589 0 : if ( pInstallFilter )
590 : {
591 0 : if ( IsFilterInstalled_Impl( pInstallFilter ) )
592 : // Maybe the filter was installed was installed afterwards.
593 0 : pFilter = pInstallFilter;
594 : }
595 : else
596 : {
597 : // Now test the filter, which first must be obtained by Star
598 : // (ErrCode is irrelevant)
599 0 : GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, 0 );
600 0 : if ( pInstallFilter )
601 0 : IsFilterInstalled_Impl( pInstallFilter );
602 : }
603 : }
604 :
605 0 : bool bHidden = bPreview;
606 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, false);
607 0 : if ( !bHidden && pFlags )
608 : {
609 0 : OUString aFlags( pFlags->GetValue() );
610 0 : aFlags = aFlags.toAsciiUpperCase();
611 0 : if( -1 != aFlags.indexOf( 'H' ) )
612 0 : bHidden = true;
613 : }
614 0 : *ppFilter = pFilter;
615 :
616 0 : if ( bHidden || (bAPI && nErr == ERRCODE_SFX_CONSULTUSER) )
617 0 : nErr = pFilter ? ERRCODE_NONE : ERRCODE_ABORT;
618 0 : return nErr;
619 : }
620 :
621 0 : const SfxFilter* SfxFilterMatcher::GetFilterForProps( const com::sun::star::uno::Sequence < beans::NamedValue >& aSeq, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
622 : {
623 0 : uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
624 0 : uno::Reference< container::XContainerQuery > xTypeCFG;
625 0 : if( xServiceManager.is() )
626 0 : xTypeCFG = uno::Reference < com::sun::star::container::XContainerQuery >( xServiceManager->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY );
627 0 : if ( xTypeCFG.is() )
628 : {
629 : // make query for all types matching the properties
630 0 : uno::Reference < com::sun::star::container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties( aSeq );
631 0 : while ( xEnum->hasMoreElements() )
632 : {
633 0 : ::comphelper::SequenceAsHashMap aProps( xEnum->nextElement() );
634 0 : OUString aValue;
635 :
636 : // try to get the preferred filter (works without loading all filters!)
637 0 : if ( (aProps[OUString("PreferredFilter")] >>= aValue) && !aValue.isEmpty() )
638 : {
639 0 : const SfxFilter* pFilter = SfxFilter::GetFilterByName( aValue );
640 0 : if ( !pFilter || (pFilter->GetFilterFlags() & nMust) != nMust || (pFilter->GetFilterFlags() & nDont ) )
641 : // check for filter flags
642 : // pFilter == 0: if preferred filter is a Writer filter, but Writer module is not installed
643 0 : continue;
644 :
645 0 : if ( !m_rImpl.aName.isEmpty() )
646 : {
647 : // if this is not the global FilterMatcher: check if filter matches the document type
648 0 : if ( pFilter->GetServiceName() != m_rImpl.aName )
649 : {
650 : // preferred filter belongs to another document type; now we must search the filter
651 0 : m_rImpl.InitForIterating();
652 0 : aProps[OUString("Name")] >>= aValue;
653 0 : pFilter = GetFilter4EA( aValue, nMust, nDont );
654 0 : if ( pFilter )
655 0 : return pFilter;
656 : }
657 : else
658 0 : return pFilter;
659 : }
660 : else
661 0 : return pFilter;
662 : }
663 0 : }
664 : }
665 :
666 0 : return 0;
667 : }
668 :
669 0 : const SfxFilter* SfxFilterMatcher::GetFilter4Mime( const OUString& rMediaType, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
670 : {
671 0 : if ( m_rImpl.pList )
672 : {
673 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
674 : {
675 0 : const SfxFilter* pFilter = (*m_rImpl.pList)[i];
676 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
677 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetMimeType() == rMediaType )
678 0 : return pFilter;
679 : }
680 :
681 0 : return 0;
682 : }
683 :
684 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
685 0 : aSeq[0].Name = "MediaType";
686 0 : aSeq[0].Value <<= rMediaType;
687 0 : return GetFilterForProps( aSeq, nMust, nDont );
688 : }
689 :
690 0 : const SfxFilter* SfxFilterMatcher::GetFilter4EA( const OUString& rType, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
691 : {
692 0 : if ( m_rImpl.pList )
693 : {
694 0 : const SfxFilter* pFirst = 0;
695 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
696 : {
697 0 : const SfxFilter* pFilter = (*m_rImpl.pList)[i];
698 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
699 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetTypeName() == rType )
700 : {
701 0 : if (nFlags & SFX_FILTER_PREFERED)
702 0 : return pFilter;
703 0 : if (!pFirst)
704 0 : pFirst = pFilter;
705 : }
706 : }
707 0 : if (pFirst)
708 0 : return pFirst;
709 :
710 0 : return 0;
711 : }
712 :
713 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
714 0 : aSeq[0].Name = "Name";
715 0 : aSeq[0].Value <<= OUString( rType );
716 0 : return GetFilterForProps( aSeq, nMust, nDont );
717 : }
718 :
719 0 : const SfxFilter* SfxFilterMatcher::GetFilter4Extension( const OUString& rExt, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
720 : {
721 0 : if ( m_rImpl.pList )
722 : {
723 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
724 : {
725 0 : const SfxFilter* pFilter = (*m_rImpl.pList)[i];
726 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
727 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
728 : {
729 0 : OUString sWildCard = ToUpper_Impl( pFilter->GetWildcard().getGlob() );
730 0 : OUString sExt = ToUpper_Impl( rExt );
731 :
732 0 : if (sExt.isEmpty())
733 0 : continue;
734 :
735 0 : if (sExt[0] != (sal_Unicode)'.')
736 0 : sExt = "." + sExt;
737 :
738 0 : WildCard aCheck(sWildCard, ';');
739 0 : if (aCheck.Matches(sExt))
740 0 : return pFilter;
741 : }
742 : }
743 :
744 0 : return 0;
745 : }
746 :
747 : // Use extension without dot!
748 0 : OUString sExt( rExt );
749 0 : if ( sExt.startsWith(".") )
750 0 : sExt = sExt.copy(1);
751 :
752 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
753 0 : aSeq[0].Name = "Extensions";
754 0 : uno::Sequence < OUString > aExts(1);
755 0 : aExts[0] = sExt;
756 0 : aSeq[0].Value <<= aExts;
757 0 : return GetFilterForProps( aSeq, nMust, nDont );
758 : }
759 :
760 0 : const SfxFilter* SfxFilterMatcher::GetFilter4ClipBoardId( sal_uInt32 nId, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
761 : {
762 0 : if (nId == 0)
763 0 : return 0;
764 :
765 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
766 0 : OUString aName = SotExchange::GetFormatName( nId );
767 0 : aSeq[0].Name = "ClipboardFormat";
768 0 : aSeq[0].Value <<= aName;
769 0 : return GetFilterForProps( aSeq, nMust, nDont );
770 : }
771 :
772 0 : const SfxFilter* SfxFilterMatcher::GetFilter4UIName( const OUString& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
773 : {
774 0 : m_rImpl.InitForIterating();
775 0 : const SfxFilter* pFirstFilter=0;
776 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
777 : {
778 0 : const SfxFilter* pFilter = (*m_rImpl.pList)[i];
779 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
780 0 : if ( (nFlags & nMust) == nMust &&
781 0 : !(nFlags & nDont ) && pFilter->GetUIName() == rName )
782 : {
783 0 : if ( pFilter->GetFilterFlags() & SFX_FILTER_PREFERED )
784 0 : return pFilter;
785 0 : else if ( !pFirstFilter )
786 0 : pFirstFilter = pFilter;
787 : }
788 : }
789 0 : return pFirstFilter;
790 : }
791 :
792 0 : const SfxFilter* SfxFilterMatcher::GetFilter4FilterName( const OUString& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
793 : {
794 0 : OUString aName( rName );
795 0 : sal_Int32 nIndex = aName.indexOf(": ");
796 0 : if ( nIndex != -1 )
797 : {
798 : SAL_WARN( "sfx.bastyp", "Old filter name used!");
799 0 : aName = rName.copy( nIndex + 2 );
800 : }
801 :
802 0 : if ( bFirstRead )
803 : {
804 0 : uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
805 0 : uno::Reference< container::XNameAccess > xFilterCFG ;
806 0 : uno::Reference< container::XNameAccess > xTypeCFG ;
807 0 : if( xServiceManager.is() )
808 : {
809 0 : xFilterCFG = uno::Reference< container::XNameAccess >( xServiceManager->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
810 0 : xTypeCFG = uno::Reference< container::XNameAccess >( xServiceManager->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY );
811 : }
812 :
813 0 : if( xFilterCFG.is() && xTypeCFG.is() )
814 : {
815 0 : if ( !pFilterArr )
816 0 : CreateFilterArr();
817 : else
818 : {
819 0 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
820 : {
821 0 : const SfxFilter* pFilter = (*pFilterArr)[i];
822 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
823 0 : if ((nFlags & nMust) == nMust && !(nFlags & nDont) && pFilter->GetFilterName().equalsIgnoreAsciiCase(aName))
824 0 : return pFilter;
825 : }
826 : }
827 :
828 0 : SfxFilterContainer::ReadSingleFilter_Impl( rName, xTypeCFG, xFilterCFG, false );
829 0 : }
830 : }
831 :
832 0 : SfxFilterList_Impl* pList = m_rImpl.pList;
833 0 : if ( !pList )
834 0 : pList = pFilterArr;
835 :
836 0 : for ( size_t i = 0, n = pList->size(); i < n; ++i )
837 : {
838 0 : const SfxFilter* pFilter = (*pList)[i];
839 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
840 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetFilterName().equalsIgnoreAsciiCase(aName))
841 0 : return pFilter;
842 : }
843 :
844 0 : return NULL;
845 : }
846 :
847 0 : IMPL_STATIC_LINK( SfxFilterMatcher, MaybeFileHdl_Impl, OUString*, pString )
848 : {
849 0 : const SfxFilter* pFilter = pThis->GetFilter4Extension( *pString, SFX_FILTER_IMPORT );
850 0 : if (pFilter && !pFilter->GetWildcard().Matches( OUString() ) &&
851 0 : !pFilter->GetWildcard().Matches(OUString("*.*")) &&
852 0 : !pFilter->GetWildcard().Matches(OUString('*'))
853 : )
854 : {
855 0 : return sal_True;
856 : }
857 0 : return sal_False;
858 : }
859 :
860 :
861 :
862 0 : SfxFilterMatcherIter::SfxFilterMatcherIter(
863 : const SfxFilterMatcher& rMatcher,
864 : SfxFilterFlags nOrMaskP, SfxFilterFlags nAndMaskP )
865 : : nOrMask( nOrMaskP ), nAndMask( nAndMaskP ),
866 0 : nCurrent(0), m_rMatch(rMatcher.m_rImpl)
867 : {
868 0 : if( nOrMask == 0xffff ) //Due to falty build on s
869 0 : nOrMask = 0;
870 0 : m_rMatch.InitForIterating();
871 0 : }
872 :
873 :
874 :
875 0 : const SfxFilter* SfxFilterMatcherIter::Find_Impl()
876 : {
877 0 : const SfxFilter* pFilter = 0;
878 0 : while( nCurrent < m_rMatch.pList->size() )
879 : {
880 0 : pFilter = (*m_rMatch.pList)[nCurrent++];
881 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
882 0 : if( ((nFlags & nOrMask) == nOrMask ) && !(nFlags & nAndMask ) )
883 0 : break;
884 0 : pFilter = 0;
885 : }
886 :
887 0 : return pFilter;
888 : }
889 :
890 0 : const SfxFilter* SfxFilterMatcherIter::First()
891 : {
892 0 : nCurrent = 0;
893 0 : return Find_Impl();
894 : }
895 :
896 :
897 :
898 0 : const SfxFilter* SfxFilterMatcherIter::Next()
899 : {
900 0 : return Find_Impl();
901 : }
902 :
903 : /*---------------------------------------------------------------
904 : helper to build own formated string from given stringlist by
905 : using given separator
906 : ---------------------------------------------------------------*/
907 0 : OUString implc_convertStringlistToString( const uno::Sequence< OUString >& lList ,
908 : const sal_Unicode& cSeparator,
909 : const OUString& sPrefix )
910 : {
911 0 : OUStringBuffer sString ( 1000 ) ;
912 0 : sal_Int32 nCount = lList.getLength();
913 0 : sal_Int32 nItem = 0 ;
914 0 : for( nItem=0; nItem<nCount; ++nItem )
915 : {
916 0 : if( !sPrefix.isEmpty() )
917 : {
918 0 : sString.append( sPrefix );
919 : }
920 0 : sString.append( lList[nItem] );
921 0 : if( nItem+1<nCount )
922 : {
923 0 : sString.append( cSeparator );
924 : }
925 : }
926 0 : return sString.makeStringAndClear();
927 : }
928 :
929 :
930 0 : void SfxFilterContainer::ReadSingleFilter_Impl(
931 : const OUString& rName,
932 : const uno::Reference< container::XNameAccess >& xTypeCFG,
933 : const uno::Reference< container::XNameAccess >& xFilterCFG,
934 : bool bUpdate
935 : )
936 : {
937 0 : OUString sFilterName( rName );
938 0 : SfxFilterList_Impl& rList = *pFilterArr;
939 0 : uno::Sequence< beans::PropertyValue > lFilterProperties;
940 0 : uno::Any aResult;
941 : try
942 : {
943 0 : aResult = xFilterCFG->getByName( sFilterName );
944 : }
945 0 : catch( container::NoSuchElementException& )
946 : {
947 0 : aResult = uno::Any();
948 : }
949 :
950 0 : if( aResult >>= lFilterProperties )
951 : {
952 : // collect information to add filter to container
953 : // (attention: some information aren't available on filter directly ... you must search for corresponding type too!)
954 0 : sal_Int32 nFlags = 0 ;
955 0 : sal_Int32 nClipboardId = 0 ;
956 0 : sal_Int32 nDocumentIconId = 0 ;
957 0 : sal_Int32 nFormatVersion = 0 ;
958 0 : OUString sMimeType ;
959 0 : OUString sType ;
960 0 : OUString sUIName ;
961 0 : OUString sHumanName ;
962 0 : OUString sDefaultTemplate ;
963 0 : OUString sUserData ;
964 0 : OUString sExtension ;
965 0 : OUString sPattern ;
966 0 : OUString sServiceName ;
967 :
968 : // first get directly available properties
969 0 : sal_Int32 nFilterPropertyCount = lFilterProperties.getLength();
970 0 : sal_Int32 nFilterProperty = 0 ;
971 0 : for( nFilterProperty=0; nFilterProperty<nFilterPropertyCount; ++nFilterProperty )
972 : {
973 0 : if ( lFilterProperties[nFilterProperty].Name == "FileFormatVersion" )
974 : {
975 0 : lFilterProperties[nFilterProperty].Value >>= nFormatVersion;
976 : }
977 0 : else if ( lFilterProperties[nFilterProperty].Name == "TemplateName" )
978 : {
979 0 : lFilterProperties[nFilterProperty].Value >>= sDefaultTemplate;
980 : }
981 0 : else if ( lFilterProperties[nFilterProperty].Name == "Flags" )
982 : {
983 0 : lFilterProperties[nFilterProperty].Value >>= nFlags;
984 : }
985 0 : else if ( lFilterProperties[nFilterProperty].Name == "UIName" )
986 : {
987 0 : lFilterProperties[nFilterProperty].Value >>= sUIName;
988 : }
989 0 : else if ( lFilterProperties[nFilterProperty].Name == "UserData" )
990 : {
991 0 : uno::Sequence< OUString > lUserData;
992 0 : lFilterProperties[nFilterProperty].Value >>= lUserData;
993 0 : sUserData = implc_convertStringlistToString( lUserData, ',', OUString() );
994 : }
995 0 : else if ( lFilterProperties[nFilterProperty].Name == "DocumentService" )
996 : {
997 0 : lFilterProperties[nFilterProperty].Value >>= sServiceName;
998 : }
999 0 : else if (lFilterProperties[nFilterProperty].Name == "ExportExtension")
1000 : {
1001 : // Extension preferred by the filter. This takes precedence
1002 : // over those that are given in the file format type.
1003 0 : lFilterProperties[nFilterProperty].Value >>= sExtension;
1004 0 : sExtension = "*." + sExtension;
1005 : }
1006 0 : else if ( lFilterProperties[nFilterProperty].Name == "Type" )
1007 : {
1008 0 : lFilterProperties[nFilterProperty].Value >>= sType;
1009 : // Try to get filter .. but look for any exceptions!
1010 : // May be filter was deleted by another thread ...
1011 : try
1012 : {
1013 0 : aResult = xTypeCFG->getByName( sType );
1014 : }
1015 0 : catch (const container::NoSuchElementException&)
1016 : {
1017 0 : aResult = uno::Any();
1018 : }
1019 :
1020 0 : uno::Sequence< beans::PropertyValue > lTypeProperties;
1021 0 : if( aResult >>= lTypeProperties )
1022 : {
1023 : // get indirect available properties then (types)
1024 0 : sal_Int32 nTypePropertyCount = lTypeProperties.getLength();
1025 0 : sal_Int32 nTypeProperty = 0 ;
1026 0 : for( nTypeProperty=0; nTypeProperty<nTypePropertyCount; ++nTypeProperty )
1027 : {
1028 0 : if ( lTypeProperties[nTypeProperty].Name == "ClipboardFormat" )
1029 : {
1030 0 : lTypeProperties[nTypeProperty].Value >>= sHumanName;
1031 : }
1032 0 : else if ( lTypeProperties[nTypeProperty].Name == "DocumentIconID" )
1033 : {
1034 0 : lTypeProperties[nTypeProperty].Value >>= nDocumentIconId;
1035 : }
1036 0 : else if ( lTypeProperties[nTypeProperty].Name == "MediaType" )
1037 : {
1038 0 : lTypeProperties[nTypeProperty].Value >>= sMimeType;
1039 : }
1040 0 : else if ( lTypeProperties[nTypeProperty].Name == "Extensions" )
1041 : {
1042 0 : if (sExtension.isEmpty())
1043 : {
1044 0 : uno::Sequence< OUString > lExtensions;
1045 0 : lTypeProperties[nTypeProperty].Value >>= lExtensions;
1046 0 : sExtension = implc_convertStringlistToString( lExtensions, ';', "*." );
1047 : }
1048 : }
1049 0 : else if ( lTypeProperties[nTypeProperty].Name == "URLPattern" )
1050 : {
1051 0 : uno::Sequence< OUString > lPattern;
1052 0 : lTypeProperties[nTypeProperty].Value >>= lPattern;
1053 0 : sPattern = implc_convertStringlistToString( lPattern, ';', OUString() );
1054 : }
1055 : }
1056 0 : }
1057 : }
1058 : }
1059 :
1060 0 : if ( sServiceName.isEmpty() )
1061 0 : return;
1062 :
1063 : // old formats are found ... using HumanPresentableName!
1064 0 : if( !sHumanName.isEmpty() )
1065 : {
1066 0 : nClipboardId = SotExchange::RegisterFormatName( sHumanName );
1067 :
1068 : // For external filters ignore clipboard IDs
1069 0 : if((nFlags & SFX_FILTER_STARONEFILTER) == SFX_FILTER_STARONEFILTER)
1070 : {
1071 0 : nClipboardId = 0;
1072 : }
1073 : }
1074 : // register SfxFilter
1075 : // first erase module name from old filter names!
1076 : // e.g: "scalc: DIF" => "DIF"
1077 0 : sal_Int32 nStartRealName = sFilterName.indexOf( ": ", 0 );
1078 0 : if( nStartRealName != -1 )
1079 : {
1080 : SAL_WARN( "sfx.bastyp", "Old format, not supported!");
1081 0 : sFilterName = sFilterName.copy( nStartRealName+2 );
1082 : }
1083 :
1084 0 : SfxFilter* pFilter = bUpdate ? (SfxFilter*) SfxFilter::GetFilterByName( sFilterName ) : 0;
1085 0 : bool bNew = false;
1086 0 : if (!pFilter)
1087 : {
1088 0 : bNew = true;
1089 : pFilter = new SfxFilter( sFilterName ,
1090 : sExtension ,
1091 : nFlags ,
1092 : nClipboardId ,
1093 : sType ,
1094 : (sal_uInt16)nDocumentIconId ,
1095 : sMimeType ,
1096 : sUserData ,
1097 0 : sServiceName );
1098 : }
1099 : else
1100 : {
1101 0 : pFilter->maFilterName = sFilterName;
1102 0 : pFilter->aWildCard = WildCard(sExtension, ';');
1103 0 : pFilter->nFormatType = nFlags;
1104 0 : pFilter->lFormat = nClipboardId;
1105 0 : pFilter->aTypeName = sType;
1106 0 : pFilter->nDocIcon = (sal_uInt16)nDocumentIconId;
1107 0 : pFilter->aMimeType = sMimeType;
1108 0 : pFilter->aUserData = sUserData;
1109 0 : pFilter->aServiceName = sServiceName;
1110 : }
1111 :
1112 : // Don't forget to set right UIName!
1113 : // Otherwise internal name is used as fallback ...
1114 0 : pFilter->SetUIName( sUIName );
1115 0 : pFilter->SetDefaultTemplate( sDefaultTemplate );
1116 0 : if( nFormatVersion )
1117 : {
1118 0 : pFilter->SetVersion( nFormatVersion );
1119 : }
1120 0 : pFilter->SetURLPattern(sPattern);
1121 :
1122 0 : if (bNew)
1123 0 : rList.push_back( pFilter );
1124 0 : }
1125 : }
1126 :
1127 0 : void SfxFilterContainer::ReadFilters_Impl( bool bUpdate )
1128 : {
1129 : SAL_INFO( "sfx.bastyp", "SfxFilterContainer::ReadFilters" );
1130 0 : if ( !pFilterArr )
1131 0 : CreateFilterArr();
1132 :
1133 0 : bFirstRead = false;
1134 0 : SfxFilterList_Impl& rList = *pFilterArr;
1135 :
1136 : try
1137 : {
1138 : // get the FilterFactory service to access the registered filters ... and types!
1139 0 : uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
1140 0 : uno::Reference< container::XNameAccess > xFilterCFG ;
1141 0 : uno::Reference< container::XNameAccess > xTypeCFG ;
1142 0 : if( xServiceManager.is() )
1143 : {
1144 0 : xFilterCFG = uno::Reference< container::XNameAccess >( xServiceManager->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY );
1145 0 : xTypeCFG = uno::Reference< container::XNameAccess >( xServiceManager->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY );
1146 : }
1147 :
1148 0 : if( xFilterCFG.is() && xTypeCFG.is() )
1149 : {
1150 : // select right query to get right set of filters for search modul
1151 0 : uno::Sequence< OUString > lFilterNames = xFilterCFG->getElementNames();
1152 0 : if ( lFilterNames.getLength() )
1153 : {
1154 : // If list of filters already exist ...
1155 : // ReadExternalFilters must work in update mode.
1156 : // Best way seems to mark all filters NOT_INSTALLED
1157 : // and change it back for all valid filters afterwards.
1158 0 : if( !rList.empty() )
1159 : {
1160 0 : bUpdate = true;
1161 : SfxFilter* pFilter;
1162 0 : for ( size_t i = 0, n = rList.size(); i < n; ++i )
1163 : {
1164 0 : pFilter = rList[ i ];
1165 0 : pFilter->nFormatType |= SFX_FILTER_NOTINSTALLED;
1166 : }
1167 : }
1168 :
1169 : // get all properties of filters ... put it into the filter container
1170 0 : sal_Int32 nFilterCount = lFilterNames.getLength();
1171 0 : sal_Int32 nFilter=0;
1172 0 : for( nFilter=0; nFilter<nFilterCount; ++nFilter )
1173 : {
1174 : // Try to get filter .. but look for any exceptions!
1175 : // May be filter was deleted by another thread ...
1176 0 : OUString sFilterName = lFilterNames[nFilter];
1177 0 : ReadSingleFilter_Impl( sFilterName, xTypeCFG, xFilterCFG, bUpdate );
1178 0 : }
1179 0 : }
1180 0 : }
1181 : }
1182 0 : catch(const uno::Exception&)
1183 : {
1184 : SAL_WARN( "sfx.bastyp", "SfxFilterContainer::ReadFilter()\nException detected. Possible not all filters could be cached.\n" );
1185 : }
1186 :
1187 0 : if ( bUpdate )
1188 : {
1189 : // global filter arry was modified, factory specific ones might need an
1190 : // update too
1191 : std::for_each(aImplArr.begin(), aImplArr.end(),
1192 0 : std::mem_fun_ref(&SfxFilterMatcher_Impl::Update));
1193 : }
1194 3 : }
1195 :
1196 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|