blob: c6273270b365463f1bb90ea993753f7ff217e795 [file] [log] [blame]
/**************************************************************
*
* 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 <svtools/filter.hxx>
#include <tools/debug.hxx>
#include <com/sun/star/uno/Any.h>
#include <unotools/processfactory.hxx>
#include <com/sun/star/uno/Exception.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#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 successfull. 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;
}
// ------------------------------------------------------------------------