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