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