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