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