1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FilterConfigCache.cxx,v $
10 * $Revision: 1.24.100.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include "FilterConfigCache.hxx"
34 #include <svtools/filter.hxx>
35 #include <tools/debug.hxx>
36 #include <com/sun/star/uno/Any.h>
37 #include <unotools/processfactory.hxx>
38 #include <com/sun/star/uno/Exception.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
42 #define TOKEN_COUNT_FOR_OWN_FILTER 3
43 // #define TOKEN_INDEX_FOR_IDENT 0
44 #define TOKEN_INDEX_FOR_FILTER 1
45 // #define TOKEN_INDEX_FOR_HASDIALOG 2
47 using namespace ::com::sun::star::lang
; // XMultiServiceFactory
48 using namespace ::com::sun::star::container
; // XNameAccess
49 using namespace ::com::sun::star::uno
; // Reference
50 using namespace ::com::sun::star::beans
; // PropertyValue
51 using namespace ::utl
; // getProcessServiceFactory();
52 using namespace ::rtl
;
54 const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList
[] =
56 IMP_BMP
, IMP_GIF
, IMP_PNG
,IMP_JPEG
, IMP_XBM
, IMP_XPM
,
57 EXP_BMP
, EXP_JPEG
, EXP_PNG
, NULL
60 const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList
[] =
62 IMP_SVMETAFILE
, IMP_WMF
, IMP_EMF
, IMP_SVSGF
, IMP_SVSGV
,
63 EXP_SVMETAFILE
, EXP_WMF
, EXP_EMF
, EXP_SVG
, NULL
66 const char* FilterConfigCache::FilterConfigCacheEntry::ExternalPixelFilterNameList
[] =
68 "egi", "icd", "ipd", "ipx", "ipb", "epb", "epg",
69 "epp", "ira", "era", "itg", "iti", "eti", "exp", NULL
72 sal_Bool
FilterConfigCache::FilterConfigCacheEntry::IsValid()
74 return sFilterName
.Len() != 0;
77 sal_Bool
FilterConfigCache::bInitialized
= sal_False
;
78 sal_Int32
FilterConfigCache::nIndType
= -1;
79 sal_Int32
FilterConfigCache::nIndUIName
= -1;
80 sal_Int32
FilterConfigCache::nIndDocumentService
= -1;
81 sal_Int32
FilterConfigCache::nIndFilterService
= -1;
82 sal_Int32
FilterConfigCache::nIndFlags
= -1;
83 sal_Int32
FilterConfigCache::nIndUserData
= -1;
84 sal_Int32
FilterConfigCache::nIndFileFormatVersion
= -1;
85 sal_Int32
FilterConfigCache::nIndTemplateName
= -1;
87 sal_Bool
FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString
& rUserDataEntry
)
89 bIsPixelFormat
= bIsInternalFilter
= sal_False
;
90 sFilterName
= String( rUserDataEntry
);
92 for ( pPtr
= InternalPixelFilterNameList
; *pPtr
&& ( bIsInternalFilter
== sal_False
); pPtr
++ )
94 if ( sFilterName
.EqualsIgnoreCaseAscii( *pPtr
) )
96 bIsInternalFilter
= sal_True
;
97 bIsPixelFormat
= sal_True
;
100 for ( pPtr
= InternalVectorFilterNameList
; *pPtr
&& ( bIsInternalFilter
== sal_False
); pPtr
++ )
102 if ( sFilterName
.EqualsIgnoreCaseAscii( *pPtr
) )
103 bIsInternalFilter
= sal_True
;
105 if ( !bIsInternalFilter
)
107 for ( pPtr
= ExternalPixelFilterNameList
; *pPtr
&& ( bIsPixelFormat
== sal_False
); pPtr
++ )
109 if ( sFilterName
.EqualsIgnoreCaseAscii( *pPtr
) )
110 bIsPixelFormat
= sal_True
;
112 String
aTemp( OUString::createFromAscii( SVLIBRARY( "?" ) ) );
113 xub_StrLen nIndex
= aTemp
.Search( (sal_Unicode
)'?' );
114 aTemp
.Replace( nIndex
, 1, sFilterName
);
117 return sFilterName
.Len() != 0;
120 String
FilterConfigCache::FilterConfigCacheEntry::GetShortName()
123 if ( lExtensionList
.getLength() )
125 aShortName
= lExtensionList
[ 0 ];
126 if ( aShortName
.SearchAscii( "*.", 0 ) == 0 )
127 aShortName
.Erase( 0, 2 );
132 /** helper to open the configuration root of the underlying
136 specify, which config package should be opened.
137 Must be one of the defined static values TYPEPKG or FILTERPKG.
139 @return A valid object if open was successfull. The access on opened
140 data will be readonly. It returns NULL in case open failed.
142 @throws It let pass RuntimeExceptions only.
144 Reference
< XInterface
> openConfig(const char* sPackage
)
145 throw(RuntimeException
)
147 static OUString
TYPEPKG( RTL_CONSTASCII_USTRINGPARAM( "types" ) );
148 static OUString
FILTERPKG( RTL_CONSTASCII_USTRINGPARAM( "filters" ) );
150 Reference
< XMultiServiceFactory
> xSMGR
= getProcessServiceFactory();
151 Reference
< XInterface
> xCfg
;
154 // get access to config API (not to file!)
155 Reference
< XMultiServiceFactory
> xConfigProvider( xSMGR
->createInstance(
156 OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), UNO_QUERY
);
158 if (xConfigProvider
.is())
160 Sequence
< Any
> lParams(1);
161 PropertyValue aParam
;
163 // define cfg path for open
164 aParam
.Name
= OUString::createFromAscii("nodepath");
165 if (TYPEPKG
.equalsIgnoreAsciiCaseAscii(sPackage
))
166 aParam
.Value
<<= OUString::createFromAscii("/org.openoffice.TypeDetection.Types/Types");
167 if (FILTERPKG
.equalsIgnoreAsciiCaseAscii(sPackage
))
168 aParam
.Value
<<= OUString::createFromAscii("/org.openoffice.TypeDetection.GraphicFilter/Filters");
169 lParams
[0] = makeAny(aParam
);
171 // get access to file
172 xCfg
= xConfigProvider
->createInstanceWithArguments(
173 OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), lParams
);
176 catch(const RuntimeException
&)
178 catch(const Exception
&)
184 void FilterConfigCache::ImplInit()
186 static OUString
STYPE ( RTL_CONSTASCII_USTRINGPARAM( "Type" ) );
187 static OUString
SUINAME ( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) );
188 static OUString
SDOCUMENTSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) );
189 static OUString
SFILTERSERVICE ( RTL_CONSTASCII_USTRINGPARAM( "FilterService" ) );
190 static OUString
STEMPLATENAME ( RTL_CONSTASCII_USTRINGPARAM( "TemplateName" ) );
191 static OUString
SFILEFORMATVERSION ( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ) );
192 static OUString
SUICOMPONENT ( RTL_CONSTASCII_USTRINGPARAM( "UIComponent" ) );
193 static OUString
SFLAGS ( RTL_CONSTASCII_USTRINGPARAM( "Flags" ) );
194 static OUString
SUSERDATA ( RTL_CONSTASCII_USTRINGPARAM( "UserData" ) );
195 static OUString
SMEDIATYPE ( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
196 static OUString
SEXTENSIONS ( RTL_CONSTASCII_USTRINGPARAM( "Extensions" ) );
197 static OUString
SFORMATNAME ( RTL_CONSTASCII_USTRINGPARAM( "FormatName" ) );
198 static OUString
SREALFILTERNAME ( RTL_CONSTASCII_USTRINGPARAM( "RealFilterName" ) );
200 // get access to config
201 Reference
< XNameAccess
> xTypeAccess ( openConfig("types" ), UNO_QUERY
);
202 Reference
< XNameAccess
> xFilterAccess( openConfig("filters"), UNO_QUERY
);
204 if ( xTypeAccess
.is() && xFilterAccess
.is() )
206 Sequence
< OUString
> lAllFilter
= xFilterAccess
->getElementNames();
207 sal_Int32 nAllFilterCount
= lAllFilter
.getLength();
209 for ( sal_Int32 i
= 0; i
< nAllFilterCount
; i
++ )
211 OUString sInternalFilterName
= lAllFilter
[ i
];
212 Reference
< XPropertySet
> xFilterSet
;
213 xFilterAccess
->getByName( sInternalFilterName
) >>= xFilterSet
;
214 if (!xFilterSet
.is())
217 FilterConfigCacheEntry aEntry
;
219 aEntry
.sInternalFilterName
= sInternalFilterName
;
220 xFilterSet
->getPropertyValue(STYPE
) >>= aEntry
.sType
;
221 xFilterSet
->getPropertyValue(SUINAME
) >>= aEntry
.sUIName
;
222 xFilterSet
->getPropertyValue(SREALFILTERNAME
) >>= aEntry
.sFilterType
;
223 Sequence
< OUString
> lFlags
;
224 xFilterSet
->getPropertyValue(SFLAGS
) >>= lFlags
;
225 if (lFlags
.getLength()!=1 || !lFlags
[0].getLength())
227 if (lFlags
[0].equalsIgnoreAsciiCaseAscii("import"))
230 if (lFlags
[0].equalsIgnoreAsciiCaseAscii("export"))
233 OUString sUIComponent
;
234 xFilterSet
->getPropertyValue(SUICOMPONENT
) >>= sUIComponent
;
235 aEntry
.bHasDialog
= sUIComponent
.getLength();
237 ::rtl::OUString sFormatName
;
238 xFilterSet
->getPropertyValue(SFORMATNAME
) >>= sFormatName
;
239 aEntry
.CreateFilterName( sFormatName
);
241 Reference
< XPropertySet
> xTypeSet
;
242 xTypeAccess
->getByName( aEntry
.sType
) >>= xTypeSet
;
246 xTypeSet
->getPropertyValue(SMEDIATYPE
) >>= aEntry
.sMediaType
;
247 xTypeSet
->getPropertyValue(SEXTENSIONS
) >>= aEntry
.lExtensionList
;
249 // The first extension will be used
250 // to generate our internal FilterType ( BMP, WMF ... )
251 String
aExtension( aEntry
.GetShortName() );
252 if (aExtension
.Len() != 3)
255 if ( aEntry
.nFlags
& 1 )
256 aImport
.push_back( aEntry
);
257 if ( aEntry
.nFlags
& 2 )
258 aExport
.push_back( aEntry
);
260 // bFilterEntryCreated!?
261 if (!( aEntry
.nFlags
& 3 ))
262 continue; //? Entry was already inserted ... but following code will be supressed?!
267 const char* FilterConfigCache::InternalFilterListForSvxLight
[] =
297 "svm","1","SVMETAFILE",
298 "svm","2","SVMETAFILE",
313 void FilterConfigCache::ImplInitSmart()
316 for ( pPtr
= InternalFilterListForSvxLight
; *pPtr
; pPtr
++ )
318 FilterConfigCacheEntry aEntry
;
320 OUString
sExtension( OUString::createFromAscii( *pPtr
++ ) );
322 aEntry
.lExtensionList
.realloc( 1 );
323 aEntry
.lExtensionList
[ 0 ] = sExtension
;
325 aEntry
.sType
= sExtension
;
326 aEntry
.sUIName
= sExtension
;
328 ByteString
sFlags( *pPtr
++ );
329 aEntry
.nFlags
= sFlags
.ToInt32();
331 OUString
sUserData( OUString::createFromAscii( *pPtr
) );
332 aEntry
.CreateFilterName( sUserData
);
334 if ( aEntry
.nFlags
& 1 )
335 aImport
.push_back( aEntry
);
336 if ( aEntry
.nFlags
& 2 )
337 aExport
.push_back( aEntry
);
341 // ------------------------------------------------------------------------
343 FilterConfigCache::FilterConfigCache( sal_Bool bConfig
) :
344 bUseConfig ( bConfig
)
352 FilterConfigCache::~FilterConfigCache()
357 String
FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat
)
359 if( nFormat
< aImport
.size() )
360 return aImport
[ nFormat
].sFilterName
;
361 return String::EmptyString();
364 sal_uInt16
FilterConfigCache::GetImportFormatNumber( const String
& rFormatName
)
366 CacheVector::iterator
aIter( aImport
.begin() );
367 while ( aIter
!= aImport
.end() )
369 if ( aIter
->sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
373 return sal::static_int_cast
< sal_uInt16
>(aIter
== aImport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aImport
.begin());
376 sal_uInt16
FilterConfigCache::GetImportFormatNumberForMediaType( const String
& rMediaType
)
378 CacheVector::iterator
aIter( aImport
.begin() );
379 while ( aIter
!= aImport
.end() )
381 if ( aIter
->sMediaType
.equalsIgnoreAsciiCase( rMediaType
) )
385 return sal::static_int_cast
< sal_uInt16
>(aIter
== aImport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aImport
.begin());
388 sal_uInt16
FilterConfigCache::GetImportFormatNumberForShortName( const String
& rShortName
)
390 CacheVector::iterator
aIter( aImport
.begin() );
391 while ( aIter
!= aImport
.end() )
393 if ( aIter
->GetShortName().EqualsIgnoreCaseAscii( rShortName
) )
397 return sal::static_int_cast
< sal_uInt16
>(aIter
== aImport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aImport
.begin());
400 sal_uInt16
FilterConfigCache::GetImportFormatNumberForTypeName( const String
& rType
)
402 CacheVector::iterator
aIter( aImport
.begin() );
403 while ( aIter
!= aImport
.end() )
405 if ( aIter
->sType
.equalsIgnoreAsciiCase( rType
) )
409 return sal::static_int_cast
< sal_uInt16
>(aIter
== aImport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aImport
.begin());
412 String
FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat
)
414 if( nFormat
< aImport
.size() )
415 return aImport
[ nFormat
].sUIName
;
416 return String::EmptyString();
419 String
FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat
)
421 if( nFormat
< aImport
.size() )
422 return aImport
[ nFormat
].sMediaType
;
423 return String::EmptyString();
426 String
FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat
)
428 if( nFormat
< aImport
.size() )
429 return aImport
[ nFormat
].GetShortName();
430 return String::EmptyString();
433 String
FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
435 if ( (nFormat
< aImport
.size()) && (nEntry
< aImport
[ nFormat
].lExtensionList
.getLength()) )
436 return aImport
[ nFormat
].lExtensionList
[ nEntry
];
437 return String::EmptyString();
440 String
FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat
)
442 if( nFormat
< aImport
.size() )
443 return aImport
[ nFormat
].sType
;
444 return String::EmptyString();
447 String
FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat
)
449 if( nFormat
< aImport
.size() )
450 return aImport
[ nFormat
].sFilterType
;
451 return String::EmptyString();
454 String
FilterConfigCache::GetImportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
456 String
aWildcard( GetImportFormatExtension( nFormat
, nEntry
) );
457 if ( aWildcard
.Len() )
458 aWildcard
.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 );
462 sal_Bool
FilterConfigCache::IsImportInternalFilter( sal_uInt16 nFormat
)
464 return (nFormat
< aImport
.size()) && aImport
[ nFormat
].bIsInternalFilter
;
467 sal_Bool
FilterConfigCache::IsImportPixelFormat( sal_uInt16 nFormat
)
469 return (nFormat
< aImport
.size()) && aImport
[ nFormat
].bIsPixelFormat
;
472 sal_Bool
FilterConfigCache::IsImportDialog( sal_uInt16 nFormat
)
474 return (nFormat
< aImport
.size()) && aImport
[ nFormat
].bHasDialog
;
477 // ------------------------------------------------------------------------
479 String
FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat
)
481 if( nFormat
< aExport
.size() )
482 return aExport
[ nFormat
].sFilterName
;
483 return String::EmptyString();
486 sal_uInt16
FilterConfigCache::GetExportFormatNumber( const String
& rFormatName
)
488 CacheVector::iterator
aIter( aExport
.begin() );
489 while ( aIter
!= aExport
.end() )
491 if ( aIter
->sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
495 return sal::static_int_cast
< sal_uInt16
>(aIter
== aExport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aExport
.begin());
498 sal_uInt16
FilterConfigCache::GetExportFormatNumberForMediaType( const String
& rMediaType
)
500 CacheVector::iterator
aIter( aExport
.begin() );
501 while ( aIter
!= aExport
.end() )
503 if ( aIter
->sMediaType
.equalsIgnoreAsciiCase( rMediaType
) )
507 return sal::static_int_cast
< sal_uInt16
>(aIter
== aExport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aExport
.begin());
510 sal_uInt16
FilterConfigCache::GetExportFormatNumberForShortName( const String
& rShortName
)
512 CacheVector::iterator
aIter( aExport
.begin() );
513 while ( aIter
!= aExport
.end() )
515 if ( aIter
->GetShortName().EqualsIgnoreCaseAscii( rShortName
) )
519 return sal::static_int_cast
< sal_uInt16
>(aIter
== aExport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aExport
.begin());
522 sal_uInt16
FilterConfigCache::GetExportFormatNumberForTypeName( const String
& rType
)
524 CacheVector::iterator
aIter( aExport
.begin() );
525 while ( aIter
!= aExport
.end() )
527 if ( aIter
->sType
.equalsIgnoreAsciiCase( rType
) )
531 return sal::static_int_cast
< sal_uInt16
>(aIter
== aExport
.end() ? GRFILTER_FORMAT_NOTFOUND
: aIter
- aExport
.begin());
534 String
FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat
)
536 if( nFormat
< aExport
.size() )
537 return aExport
[ nFormat
].sUIName
;
538 return String::EmptyString();
541 String
FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat
)
543 if( nFormat
< aExport
.size() )
544 return aExport
[ nFormat
].sMediaType
;
545 return String::EmptyString();
548 String
FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat
)
550 if( nFormat
< aExport
.size() )
551 return aExport
[ nFormat
].GetShortName();
552 return String::EmptyString();
555 String
FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
557 if ( (nFormat
< aExport
.size()) && (nEntry
< aExport
[ nFormat
].lExtensionList
.getLength()) )
558 return aExport
[ nFormat
].lExtensionList
[ nEntry
];
559 return String::EmptyString();
562 String
FilterConfigCache::GetExportFilterTypeName( sal_uInt16 nFormat
)
564 if( nFormat
< aExport
.size() )
565 return aExport
[ nFormat
].sFilterType
;
566 return String::EmptyString();
569 String
FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat
)
571 if( nFormat
< aExport
.size() )
572 return aExport
[ nFormat
].sInternalFilterName
;
573 return String::EmptyString();
576 String
FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
578 String
aWildcard( GetExportFormatExtension( nFormat
, nEntry
) );
579 if ( aWildcard
.Len() )
580 aWildcard
.Insert( UniString::CreateFromAscii( "*.", 2 ), 0 );
584 sal_Bool
FilterConfigCache::IsExportInternalFilter( sal_uInt16 nFormat
)
586 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bIsInternalFilter
;
589 sal_Bool
FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat
)
591 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bIsPixelFormat
;
594 sal_Bool
FilterConfigCache::IsExportDialog( sal_uInt16 nFormat
)
596 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bHasDialog
;
599 // ------------------------------------------------------------------------