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