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 delete pImpl; 191 } 192 193 //---------------------------------------------------------------- 194 195 const String SfxFilterContainer::GetName() const 196 { 197 return pImpl->aName; 198 } 199 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(); 270 SfxFilterMatcher_Impl() 271 : pList(0) 272 {} 273 }; 274 275 DECL_PTRARRAY( SfxFilterMatcherArr_Impl, SfxFilterMatcher_Impl*, 2, 2 ) 276 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 303 SfxFilterMatcher::SfxFilterMatcher() 304 { 305 // global FilterMatcher always uses global filter array (also created on demand) 306 pImpl = new SfxFilterMatcher_Impl; 307 } 308 309 SfxFilterMatcher::~SfxFilterMatcher() 310 { 311 if ( !pImpl->aName.getLength() ) 312 // only the global Matcher owns his ImplData 313 delete pImpl; 314 } 315 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 331 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 353 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 370 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 412 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 419 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 //---------------------------------------------------------------- 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 521 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 596 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 645 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 667 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 697 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 739 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 751 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 772 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 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 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 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 867 const SfxFilter* SfxFilterMatcherIter::First() 868 { 869 nCurrent = 0; 870 return Find_Impl(); 871 } 872 873 //---------------------------------------------------------------- 874 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 ---------------------------------------------------------------*/ 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 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 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