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