/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svtools.hxx" #include "FilterConfigCache.hxx" #include #include #include #include #include #include #include #define TOKEN_COUNT_FOR_OWN_FILTER 3 // #define TOKEN_INDEX_FOR_IDENT 0 #define TOKEN_INDEX_FOR_FILTER 1 // #define TOKEN_INDEX_FOR_HASDIALOG 2 using namespace ::com::sun::star::lang ; // XMultiServiceFactory using namespace ::com::sun::star::container ; // XNameAccess using namespace ::com::sun::star::uno ; // Reference using namespace ::com::sun::star::beans ; // PropertyValue using namespace ::utl ; // getProcessServiceFactory(); using ::rtl::OUString; const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList[] = { IMP_BMP, IMP_GIF, IMP_PNG,IMP_JPEG, IMP_XBM, IMP_XPM, EXP_BMP, EXP_JPEG, EXP_PNG, NULL }; const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList[] = { IMP_SVMETAFILE, IMP_WMF, IMP_EMF, IMP_SVSGF, IMP_SVSGV, IMP_SVG, EXP_SVMETAFILE, EXP_WMF, EXP_EMF, EXP_SVG, NULL }; const char* FilterConfigCache::FilterConfigCacheEntry::ExternalPixelFilterNameList[] = { "egi", "icd", "ipd", "ipx", "ipb", "epb", "epg", "epp", "ira", "era", "itg", "iti", "eti", "exp", NULL }; sal_Bool FilterConfigCache::FilterConfigCacheEntry::IsValid() { return sFilterName.Len() != 0; } sal_Bool FilterConfigCache::bInitialized = sal_False; sal_Int32 FilterConfigCache::nIndType = -1; sal_Int32 FilterConfigCache::nIndUIName = -1; sal_Int32 FilterConfigCache::nIndDocumentService = -1; sal_Int32 FilterConfigCache::nIndFilterService = -1; sal_Int32 FilterConfigCache::nIndFlags = -1; sal_Int32 FilterConfigCache::nIndUserData = -1; sal_Int32 FilterConfigCache::nIndFileFormatVersion = -1; sal_Int32 FilterConfigCache::nIndTemplateName = -1; sal_Bool FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString& rUserDataEntry ) { bIsPixelFormat = bIsInternalFilter = sal_False; sFilterName = String( rUserDataEntry ); const char** pPtr; for ( pPtr = InternalPixelFilterNameList; *pPtr && ( bIsInternalFilter == sal_False ); pPtr++ ) { if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) ) { bIsInternalFilter = sal_True; bIsPixelFormat = sal_True; } } for ( pPtr = InternalVectorFilterNameList; *pPtr && ( bIsInternalFilter == sal_False ); pPtr++ ) { if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) ) bIsInternalFilter = sal_True; } if ( !bIsInternalFilter ) { for ( pPtr = ExternalPixelFilterNameList; *pPtr && ( bIsPixelFormat == sal_False ); pPtr++ ) { if ( sFilterName.EqualsIgnoreCaseAscii( *pPtr ) ) bIsPixelFormat = sal_True; } String aTemp( OUString::createFromAscii( SVLIBRARY( "?" ) ) ); xub_StrLen nIndex = aTemp.Search( (sal_Unicode)'?' ); aTemp.Replace( nIndex, 1, sFilterName ); sFilterName = aTemp; } return sFilterName.Len() != 0; } String FilterConfigCache::FilterConfigCacheEntry::GetShortName() { String aShortName; if ( lExtensionList.getLength() ) { aShortName = lExtensionList[ 0 ]; if ( aShortName.SearchAscii( "*.", 0 ) == 0 ) aShortName.Erase( 0, 2 ); } return aShortName; } /** helper to open the configuration root of the underlying config package @param sPackage specify, which config package should be opened. Must be one of the defined static values TYPEPKG or FILTERPKG. @return A valid object if open was successful. The access on opened data will be readonly. It returns NULL in case open failed. @throws It let pass RuntimeExceptions only. */ Reference< XInterface > openConfig(const char* sPackage) throw(RuntimeException) { static OUString TYPEPKG( RTL_CONSTASCII_USTRINGPARAM( "types" ) ); static OUString FILTERPKG( RTL_CONSTASCII_USTRINGPARAM( "filters" ) ); Reference< XMultiServiceFactory > xSMGR = getProcessServiceFactory(); Reference< XInterface > xCfg; try { // get access to config API (not to file!) Reference< XMultiServiceFactory > xConfigProvider( xSMGR->createInstance( OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), UNO_QUERY); if (xConfigProvider.is()) { Sequence< Any > lParams(1); PropertyValue aParam ; // define cfg path for open aParam.Name = OUString::createFromAscii("nodepath"); if (TYPEPKG.equalsIgnoreAsciiCaseAscii(sPackage)) aParam.Value <<= OUString::createFromAscii("/org.openoffice.TypeDetection.Types/Types"); if (FILTERPKG.equalsIgnoreAsciiCaseAscii(sPackage)) aParam.Value <<= OUString::createFromAscii("/org.openoffice.TypeDetection.GraphicFilter/Filters"); lParams[0] = makeAny(aParam); // get access to file xCfg = xConfigProvider->createInstanceWithArguments( OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), lParams); } } catch(const RuntimeException&) { throw; } catch(const Exception&) { xCfg.clear(); } return xCfg; } void FilterConfigCache::ImplInit() { static OUString STYPE ( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ); static OUString SUINAME ( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) ); static OUString SDOCUMENTSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) ); static OUString SFILTERSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ) ); static OUString STEMPLATENAME ( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" ) ); static OUString SFILEFORMATVERSION ( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ) ); static OUString SUICOMPONENT ( RTL_CONSTASCII_USTRINGPARAM( "UIComponent" ) ); static OUString SFLAGS ( RTL_CONSTASCII_USTRINGPARAM( "Flags" ) ); static OUString SUSERDATA ( RTL_CONSTASCII_USTRINGPARAM( "UserData" ) ); static OUString SMEDIATYPE ( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ); static OUString SEXTENSIONS ( RTL_CONSTASCII_USTRINGPARAM( "Extensions" ) ); static OUString SFORMATNAME ( RTL_CONSTASCII_USTRINGPARAM( "FormatName" ) ); static OUString SREALFILTERNAME ( RTL_CONSTASCII_USTRINGPARAM( "RealFilterName" ) ); // get access to config Reference< XNameAccess > xTypeAccess ( openConfig("types" ), UNO_QUERY ); Reference< XNameAccess > xFilterAccess( openConfig("filters"), UNO_QUERY ); if ( xTypeAccess.is() && xFilterAccess.is() ) { Sequence< OUString > lAllFilter = xFilterAccess->getElementNames(); sal_Int32 nAllFilterCount = lAllFilter.getLength(); for ( sal_Int32 i = 0; i < nAllFilterCount; i++ ) { OUString sInternalFilterName = lAllFilter[ i ]; Reference< XPropertySet > xFilterSet; xFilterAccess->getByName( sInternalFilterName ) >>= xFilterSet; if (!xFilterSet.is()) continue; FilterConfigCacheEntry aEntry; aEntry.sInternalFilterName = sInternalFilterName; xFilterSet->getPropertyValue(STYPE) >>= aEntry.sType; xFilterSet->getPropertyValue(SUINAME) >>= aEntry.sUIName; xFilterSet->getPropertyValue(SREALFILTERNAME) >>= aEntry.sFilterType; Sequence< OUString > lFlags; xFilterSet->getPropertyValue(SFLAGS) >>= lFlags; if (lFlags.getLength()!=1 || !lFlags[0].getLength()) continue; if (lFlags[0].equalsIgnoreAsciiCaseAscii("import")) aEntry.nFlags = 1; else if (lFlags[0].equalsIgnoreAsciiCaseAscii("export")) aEntry.nFlags = 2; OUString sUIComponent; xFilterSet->getPropertyValue(SUICOMPONENT) >>= sUIComponent; aEntry.bHasDialog = sUIComponent.getLength(); ::rtl::OUString sFormatName; xFilterSet->getPropertyValue(SFORMATNAME) >>= sFormatName; aEntry.CreateFilterName( sFormatName ); Reference< XPropertySet > xTypeSet; xTypeAccess->getByName( aEntry.sType ) >>= xTypeSet; if (!xTypeSet.is()) continue; xTypeSet->getPropertyValue(SMEDIATYPE) >>= aEntry.sMediaType; xTypeSet->getPropertyValue(SEXTENSIONS) >>= aEntry.lExtensionList; // The first extension will be used // to generate our internal FilterType ( BMP, WMF ... ) String aExtension( aEntry.GetShortName() ); if (aExtension.Len() != 3) continue; if ( aEntry.nFlags & 1 ) aImport.push_back( aEntry ); if ( aEntry.nFlags & 2 ) aExport.push_back( aEntry ); // bFilterEntryCreated!? if (!( aEntry.nFlags & 3 )) continue; //? Entry was already inserted ... but following code will be supressed?! } } }; const char* FilterConfigCache::InternalFilterListForSvxLight[] = { "bmp","1","SVBMP", "bmp","2","SVBMP", "dxf","1","idx", "eps","1","ips", "eps","2","eps", "gif","1","SVIGIF", "gif","2","egi", "jpg","1","SVIJPEG", "jpg","2","SVEJPEG", "sgv","1","SVSGV", "sgf","1","SVSGF", "met","1","ime", "met","2","eme", "png","1","SVIPNG", "png","2","SVEPNG", "pct","1","ipt", "pct","2","ept", "pcd","1","icd", "psd","1","ipd", "pcx","1","ipx", "pbm","1","ipb", "pbm","2","epb", "pgm","1","ipb", "pgm","2","epg", "ppm","1","ipb", "ppm","2","epp", "ras","1","ira", "ras","2","era", "svm","1","SVMETAFILE", "svm","2","SVMETAFILE", "tga","1","itg", "tif","1","iti", "tif","2","eti", "emf","1","SVEMF", "emf","2","SVEMF", "wmf","1","SVWMF", "wmf","2","SVWMF", "xbm","1","SVIXBM", "xpm","1","SVIXPM", "xpm","2","exp", "svg","1","SVISVG", "svg","2","SVESVG", NULL }; void FilterConfigCache::ImplInitSmart() { const char** pPtr; for ( pPtr = InternalFilterListForSvxLight; *pPtr; pPtr++ ) { FilterConfigCacheEntry aEntry; OUString sExtension( OUString::createFromAscii( *pPtr++ ) ); aEntry.lExtensionList.realloc( 1 ); aEntry.lExtensionList[ 0 ] = sExtension; aEntry.sType = sExtension; aEntry.sUIName = sExtension; ByteString sFlags( *pPtr++ ); aEntry.nFlags = sFlags.ToInt32(); OUString sUserData( OUString::createFromAscii( *pPtr ) ); aEntry.CreateFilterName( sUserData ); if ( aEntry.nFlags & 1 ) aImport.push_back( aEntry ); if ( aEntry.nFlags & 2 ) aExport.push_back( aEntry ); } } // ------------------------------------------------------------------------ FilterConfigCache::FilterConfigCache( sal_Bool bConfig ) : bUseConfig ( bConfig ) { if ( bUseConfig ) ImplInit(); else ImplInitSmart(); } FilterConfigCache::~FilterConfigCache() { } String FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].sFilterName; return String::EmptyString(); } sal_uInt16 FilterConfigCache::GetImportFormatNumber( const String& rFormatName ) { CacheVector::iterator aIter( aImport.begin() ); while ( aIter != aImport.end() ) { if ( aIter->sUIName.equalsIgnoreAsciiCase( rFormatName ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin()); } sal_uInt16 FilterConfigCache::GetImportFormatNumberForMediaType( const String& rMediaType ) { CacheVector::iterator aIter( aImport.begin() ); while ( aIter != aImport.end() ) { if ( aIter->sMediaType.equalsIgnoreAsciiCase( rMediaType ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin()); } sal_uInt16 FilterConfigCache::GetImportFormatNumberForShortName( const String& rShortName ) { CacheVector::iterator aIter( aImport.begin() ); while ( aIter != aImport.end() ) { if ( aIter->GetShortName().EqualsIgnoreCaseAscii( rShortName ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin()); } sal_uInt16 FilterConfigCache::GetImportFormatNumberForTypeName( const String& rType ) { CacheVector::iterator aIter( aImport.begin() ); while ( aIter != aImport.end() ) { if ( aIter->sType.equalsIgnoreAsciiCase( rType ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aImport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aImport.begin()); } String FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].sUIName; return String::EmptyString(); } String FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].sMediaType; return String::EmptyString(); } String FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].GetShortName(); return String::EmptyString(); } String FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry ) { if ( (nFormat < aImport.size()) && (nEntry < aImport[ nFormat ].lExtensionList.getLength()) ) return aImport[ nFormat ].lExtensionList[ nEntry ]; return String::EmptyString(); } String FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].sType; return String::EmptyString(); } String FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat ) { if( nFormat < aImport.size() ) return aImport[ nFormat ].sFilterType; return String::EmptyString(); } String FilterConfigCache::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry ) { String aWildcard( GetImportFormatExtension( nFormat, nEntry ) ); if ( aWildcard.Len() ) aWildcard.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 ); return aWildcard; } sal_Bool FilterConfigCache::IsImportInternalFilter( sal_uInt16 nFormat ) { return (nFormat < aImport.size()) && aImport[ nFormat ].bIsInternalFilter; } sal_Bool FilterConfigCache::IsImportPixelFormat( sal_uInt16 nFormat ) { return (nFormat < aImport.size()) && aImport[ nFormat ].bIsPixelFormat; } sal_Bool FilterConfigCache::IsImportDialog( sal_uInt16 nFormat ) { return (nFormat < aImport.size()) && aImport[ nFormat ].bHasDialog; } // ------------------------------------------------------------------------ String FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].sFilterName; return String::EmptyString(); } sal_uInt16 FilterConfigCache::GetExportFormatNumber( const String& rFormatName ) { CacheVector::iterator aIter( aExport.begin() ); while ( aIter != aExport.end() ) { if ( aIter->sUIName.equalsIgnoreAsciiCase( rFormatName ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin()); } sal_uInt16 FilterConfigCache::GetExportFormatNumberForMediaType( const String& rMediaType ) { CacheVector::iterator aIter( aExport.begin() ); while ( aIter != aExport.end() ) { if ( aIter->sMediaType.equalsIgnoreAsciiCase( rMediaType ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin()); } sal_uInt16 FilterConfigCache::GetExportFormatNumberForShortName( const String& rShortName ) { CacheVector::iterator aIter( aExport.begin() ); while ( aIter != aExport.end() ) { if ( aIter->GetShortName().EqualsIgnoreCaseAscii( rShortName ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin()); } sal_uInt16 FilterConfigCache::GetExportFormatNumberForTypeName( const String& rType ) { CacheVector::iterator aIter( aExport.begin() ); while ( aIter != aExport.end() ) { if ( aIter->sType.equalsIgnoreAsciiCase( rType ) ) break; aIter++; } return sal::static_int_cast< sal_uInt16 >(aIter == aExport.end() ? GRFILTER_FORMAT_NOTFOUND : aIter - aExport.begin()); } String FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].sUIName; return String::EmptyString(); } String FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].sMediaType; return String::EmptyString(); } String FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].GetShortName(); return String::EmptyString(); } String FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry ) { if ( (nFormat < aExport.size()) && (nEntry < aExport[ nFormat ].lExtensionList.getLength()) ) return aExport[ nFormat ].lExtensionList[ nEntry ]; return String::EmptyString(); } String FilterConfigCache::GetExportFilterTypeName( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].sFilterType; return String::EmptyString(); } String FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat ) { if( nFormat < aExport.size() ) return aExport[ nFormat ].sInternalFilterName; return String::EmptyString(); } String FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry ) { String aWildcard( GetExportFormatExtension( nFormat, nEntry ) ); if ( aWildcard.Len() ) aWildcard.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 ); return aWildcard; } sal_Bool FilterConfigCache::IsExportInternalFilter( sal_uInt16 nFormat ) { return (nFormat < aExport.size()) && aExport[ nFormat ].bIsInternalFilter; } sal_Bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat ) { return (nFormat < aExport.size()) && aExport[ nFormat ].bIsPixelFormat; } sal_Bool FilterConfigCache::IsExportDialog( sal_uInt16 nFormat ) { return (nFormat < aExport.size()) && aExport[ nFormat ].bHasDialog; } // ------------------------------------------------------------------------