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