1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "FilterConfigCache.hxx"
22 #include <vcl/graphicfilter.hxx>
23 #include <com/sun/star/uno/Any.h>
24 #include <comphelper/processfactory.hxx>
25 #include <com/sun/star/uno/Exception.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/configuration/theDefaultProvider.hpp>
29 #include <com/sun/star/container/XNameAccess.hpp>
31 using namespace ::com::sun::star::lang
; // XMultiServiceFactory
32 using namespace ::com::sun::star::container
; // XNameAccess
33 using namespace ::com::sun::star::uno
; // Reference
34 using namespace ::com::sun::star::beans
; // PropertyValue
35 using namespace ::com::sun::star::configuration
;
37 const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList
[] =
39 IMP_BMP
, IMP_GIF
, IMP_PNG
,IMP_JPEG
, IMP_XBM
, IMP_XPM
,
40 EXP_BMP
, EXP_JPEG
, EXP_PNG
, IMP_MOV
, NULL
43 const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList
[] =
45 IMP_SVMETAFILE
, IMP_WMF
, IMP_EMF
, IMP_SVSGF
, IMP_SVSGV
, IMP_SVG
,
46 EXP_SVMETAFILE
, EXP_WMF
, EXP_EMF
, EXP_SVG
, NULL
49 const char* FilterConfigCache::FilterConfigCacheEntry::ExternalPixelFilterNameList
[] =
51 "egi", "icd", "ipd", "ipx", "ipb", "epb", "epg",
52 "epp", "ira", "era", "itg", "iti", "eti", "exp", NULL
55 bool FilterConfigCache::bInitialized
= false;
56 sal_Int32
FilterConfigCache::nIndType
= -1;
57 sal_Int32
FilterConfigCache::nIndUIName
= -1;
58 sal_Int32
FilterConfigCache::nIndDocumentService
= -1;
59 sal_Int32
FilterConfigCache::nIndFilterService
= -1;
60 sal_Int32
FilterConfigCache::nIndFlags
= -1;
61 sal_Int32
FilterConfigCache::nIndUserData
= -1;
62 sal_Int32
FilterConfigCache::nIndFileFormatVersion
= -1;
63 sal_Int32
FilterConfigCache::nIndTemplateName
= -1;
65 bool FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString
& rUserDataEntry
)
67 bIsPixelFormat
= bIsInternalFilter
= false;
68 sFilterName
= rUserDataEntry
;
70 for ( pPtr
= InternalPixelFilterNameList
; *pPtr
&& !bIsInternalFilter
; pPtr
++ )
72 if ( sFilterName
.equalsIgnoreAsciiCase( OUString(*pPtr
, strlen(*pPtr
), RTL_TEXTENCODING_ASCII_US
) ) )
74 bIsInternalFilter
= true;
75 bIsPixelFormat
= true;
78 for ( pPtr
= InternalVectorFilterNameList
; *pPtr
&& !bIsInternalFilter
; pPtr
++ )
80 if ( sFilterName
.equalsIgnoreAsciiCase( OUString(*pPtr
, strlen(*pPtr
), RTL_TEXTENCODING_ASCII_US
) ) )
81 bIsInternalFilter
= true;
83 if ( !bIsInternalFilter
)
85 for ( pPtr
= ExternalPixelFilterNameList
; *pPtr
&& !bIsPixelFormat
; pPtr
++ )
87 if ( sFilterName
.equalsIgnoreAsciiCase( OUString(*pPtr
, strlen(*pPtr
), RTL_TEXTENCODING_ASCII_US
) ) )
88 bIsPixelFormat
= true;
90 OUString
sTemp(SVLIBRARY("?"));
91 sFilterName
= sTemp
.replaceFirst("?", sFilterName
);
93 return ! sFilterName
.isEmpty();
96 OUString
FilterConfigCache::FilterConfigCacheEntry::GetShortName()
99 if ( lExtensionList
.getLength() )
101 aShortName
= lExtensionList
[ 0 ];
102 if ( aShortName
.startsWith( "*." ) )
103 aShortName
= aShortName
.replaceAt( 0, 2, "" );
108 /** helper to open the configuration root of the underlying
112 specify, which config package should be opened.
113 Must be one of "types" or "filters"
115 @return A valid object if open was successful. The access on opened
116 data will be readonly. It returns NULL in case open failed.
118 @throws It let pass RuntimeExceptions only.
120 Reference
< XInterface
> openConfig(const char* sPackage
)
121 throw(RuntimeException
)
123 Reference
< XComponentContext
> xContext(
124 comphelper::getProcessComponentContext() );
125 Reference
< XInterface
> xCfg
;
128 // get access to config API (not to file!)
129 Reference
< XMultiServiceFactory
> xConfigProvider
= theDefaultProvider::get( xContext
);
131 Sequence
< Any
> lParams(1);
132 PropertyValue aParam
;
134 // define cfg path for open
135 aParam
.Name
= "nodepath";
136 if (rtl_str_compareIgnoreAsciiCase(sPackage
, "types") == 0)
137 aParam
.Value
<<= OUString( "/org.openoffice.TypeDetection.Types/Types" );
138 if (rtl_str_compareIgnoreAsciiCase(sPackage
, "filters") == 0)
139 aParam
.Value
<<= OUString( "/org.openoffice.TypeDetection.GraphicFilter/Filters" );
140 lParams
[0] = makeAny(aParam
);
142 // get access to file
143 xCfg
= xConfigProvider
->createInstanceWithArguments(
144 OUString( "com.sun.star.configuration.ConfigurationAccess" ), lParams
);
146 catch(const RuntimeException
&)
148 catch(const Exception
&)
154 void FilterConfigCache::ImplInit()
156 OUString
STYPE ( "Type" );
157 OUString
SUINAME ( "UIName" );
158 OUString
SFLAGS ( "Flags" );
159 OUString
SMEDIATYPE ( "MediaType" );
160 OUString
SEXTENSIONS ( "Extensions" );
161 OUString
SFORMATNAME ( "FormatName" );
162 OUString
SREALFILTERNAME ( "RealFilterName" );
164 // get access to config
165 Reference
< XNameAccess
> xTypeAccess ( openConfig("types" ), UNO_QUERY
);
166 Reference
< XNameAccess
> xFilterAccess( openConfig("filters"), UNO_QUERY
);
168 if ( xTypeAccess
.is() && xFilterAccess
.is() )
170 Sequence
< OUString
> lAllFilter
= xFilterAccess
->getElementNames();
171 sal_Int32 nAllFilterCount
= lAllFilter
.getLength();
173 for ( sal_Int32 i
= 0; i
< nAllFilterCount
; i
++ )
175 OUString sInternalFilterName
= lAllFilter
[ i
];
176 Reference
< XPropertySet
> xFilterSet
;
177 xFilterAccess
->getByName( sInternalFilterName
) >>= xFilterSet
;
178 if (!xFilterSet
.is())
181 FilterConfigCacheEntry aEntry
;
183 aEntry
.sInternalFilterName
= sInternalFilterName
;
184 xFilterSet
->getPropertyValue(STYPE
) >>= aEntry
.sType
;
185 xFilterSet
->getPropertyValue(SUINAME
) >>= aEntry
.sUIName
;
186 xFilterSet
->getPropertyValue(SREALFILTERNAME
) >>= aEntry
.sFilterType
;
187 Sequence
< OUString
> lFlags
;
188 xFilterSet
->getPropertyValue(SFLAGS
) >>= lFlags
;
189 if (lFlags
.getLength()!=1 || lFlags
[0].isEmpty())
191 if (lFlags
[0].equalsIgnoreAsciiCase("import"))
193 else if (lFlags
[0].equalsIgnoreAsciiCase("export"))
196 OUString sFormatName
;
197 xFilterSet
->getPropertyValue(SFORMATNAME
) >>= sFormatName
;
198 aEntry
.CreateFilterName( sFormatName
);
200 Reference
< XPropertySet
> xTypeSet
;
201 xTypeAccess
->getByName( aEntry
.sType
) >>= xTypeSet
;
205 xTypeSet
->getPropertyValue(SMEDIATYPE
) >>= aEntry
.sMediaType
;
206 xTypeSet
->getPropertyValue(SEXTENSIONS
) >>= aEntry
.lExtensionList
;
208 // The first extension will be used
209 // to generate our internal FilterType ( BMP, WMF ... )
210 OUString
aExtension( aEntry
.GetShortName() );
211 if (aExtension
.getLength() != 3)
214 if ( aEntry
.nFlags
& 1 )
215 aImport
.push_back( aEntry
);
216 if ( aEntry
.nFlags
& 2 )
217 aExport
.push_back( aEntry
);
219 // bFilterEntryCreated!?
220 if (!( aEntry
.nFlags
& 3 ))
221 continue; //? Entry was already inserted ... but following code will be suppressed?!
226 const char* FilterConfigCache::InternalFilterListForSvxLight
[] =
258 "svm","1","SVMETAFILE",
259 "svm","2","SVMETAFILE",
275 void FilterConfigCache::ImplInitSmart()
278 for ( pPtr
= InternalFilterListForSvxLight
; *pPtr
; pPtr
++ )
280 FilterConfigCacheEntry aEntry
;
282 OUString
sExtension( OUString::createFromAscii( *pPtr
++ ) );
284 aEntry
.lExtensionList
.realloc( 1 );
285 aEntry
.lExtensionList
[ 0 ] = sExtension
;
287 aEntry
.sType
= sExtension
;
288 aEntry
.sUIName
= sExtension
;
290 OString
sFlags( *pPtr
++ );
291 aEntry
.nFlags
= sFlags
.toInt32();
293 OUString
sUserData( OUString::createFromAscii( *pPtr
) );
294 aEntry
.CreateFilterName( sUserData
);
296 if ( aEntry
.nFlags
& 1 )
297 aImport
.push_back( aEntry
);
298 if ( aEntry
.nFlags
& 2 )
299 aExport
.push_back( aEntry
);
303 FilterConfigCache::FilterConfigCache( bool bConfig
) :
304 bUseConfig ( bConfig
)
312 FilterConfigCache::~FilterConfigCache()
316 OUString
FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat
)
318 if( nFormat
< aImport
.size() )
319 return aImport
[ nFormat
].sFilterName
;
323 sal_uInt16
FilterConfigCache::GetImportFormatNumber( const OUString
& rFormatName
)
325 CacheVector::const_iterator aIter
, aEnd
;
326 for (aIter
= aImport
.begin(), aEnd
= aImport
.end(); aIter
!= aEnd
; ++aIter
)
328 if ( aIter
->sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
329 return sal::static_int_cast
< sal_uInt16
>(aIter
- aImport
.begin());
331 return GRFILTER_FORMAT_NOTFOUND
;
334 /// get the index of the filter that matches this extension
335 sal_uInt16
FilterConfigCache::GetImportFormatNumberForExtension( const OUString
& rExt
)
337 CacheVector::const_iterator aIter
, aEnd
;
338 for (aIter
= aImport
.begin(), aEnd
= aImport
.end(); aIter
!= aEnd
; ++aIter
)
340 for ( sal_Int32 i
= 0; i
< aIter
->lExtensionList
.getLength(); i
++ )
342 if ( aIter
->lExtensionList
[i
].equalsIgnoreAsciiCase( rExt
) )
343 return sal::static_int_cast
< sal_uInt16
>( aIter
- aImport
.begin() );
346 return GRFILTER_FORMAT_NOTFOUND
;
349 sal_uInt16
FilterConfigCache::GetImportFormatNumberForMediaType( const OUString
& rMediaType
)
351 CacheVector::const_iterator aIter
, aEnd
;
352 for (aIter
= aImport
.begin(), aEnd
= aImport
.end(); aIter
!= aEnd
; ++aIter
)
354 if ( aIter
->sMediaType
.equalsIgnoreAsciiCase( rMediaType
) )
355 return sal::static_int_cast
< sal_uInt16
>(aIter
- aImport
.begin());
357 return GRFILTER_FORMAT_NOTFOUND
;
360 sal_uInt16
FilterConfigCache::GetImportFormatNumberForShortName( const OUString
& rShortName
)
362 CacheVector::const_iterator aEnd
;
363 CacheVector::iterator aIter
;
364 for (aIter
= aImport
.begin(), aEnd
= aImport
.end(); aIter
!= aEnd
; ++aIter
)
366 if ( aIter
->GetShortName().equalsIgnoreAsciiCase( rShortName
) )
367 return sal::static_int_cast
< sal_uInt16
>(aIter
- aImport
.begin());
369 return GRFILTER_FORMAT_NOTFOUND
;
372 sal_uInt16
FilterConfigCache::GetImportFormatNumberForTypeName( const OUString
& rType
)
374 CacheVector::const_iterator aIter
, aEnd
;
375 for (aIter
= aImport
.begin(), aEnd
= aImport
.end(); aIter
!= aEnd
; ++aIter
)
377 if ( aIter
->sType
.equalsIgnoreAsciiCase( rType
) )
378 return sal::static_int_cast
< sal_uInt16
>(aIter
- aImport
.begin());
380 return GRFILTER_FORMAT_NOTFOUND
;
383 OUString
FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat
)
385 if( nFormat
< aImport
.size() )
386 return aImport
[ nFormat
].sUIName
;
390 OUString
FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat
)
392 if( nFormat
< aImport
.size() )
393 return aImport
[ nFormat
].sMediaType
;
397 OUString
FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat
)
399 if( nFormat
< aImport
.size() )
400 return aImport
[ nFormat
].GetShortName();
404 OUString
FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
406 if ( (nFormat
< aImport
.size()) && (nEntry
< aImport
[ nFormat
].lExtensionList
.getLength()) )
407 return aImport
[ nFormat
].lExtensionList
[ nEntry
];
411 OUString
FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat
)
413 if( nFormat
< aImport
.size() )
414 return aImport
[ nFormat
].sType
;
418 OUString
FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat
)
420 if( nFormat
< aImport
.size() )
421 return aImport
[ nFormat
].sFilterType
;
425 OUString
FilterConfigCache::GetImportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
427 OUString
aWildcard( GetImportFormatExtension( nFormat
, nEntry
) );
428 if ( !aWildcard
.isEmpty() )
429 aWildcard
= aWildcard
.replaceAt( 0, 0, "*." );
433 bool FilterConfigCache::IsImportInternalFilter( sal_uInt16 nFormat
)
435 return (nFormat
< aImport
.size()) && aImport
[ nFormat
].bIsInternalFilter
;
438 bool FilterConfigCache::IsImportPixelFormat( sal_uInt16 nFormat
)
440 return (nFormat
< aImport
.size()) && aImport
[ nFormat
].bIsPixelFormat
;
443 OUString
FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat
)
445 if( nFormat
< aExport
.size() )
446 return aExport
[ nFormat
].sFilterName
;
450 sal_uInt16
FilterConfigCache::GetExportFormatNumber( const OUString
& rFormatName
)
452 CacheVector::const_iterator aIter
, aEnd
;
453 for (aIter
= aExport
.begin(), aEnd
= aExport
.end(); aIter
!= aEnd
; ++aIter
)
455 if ( aIter
->sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
456 return sal::static_int_cast
< sal_uInt16
>(aIter
- aExport
.begin());
458 return GRFILTER_FORMAT_NOTFOUND
;
461 sal_uInt16
FilterConfigCache::GetExportFormatNumberForMediaType( const OUString
& rMediaType
)
463 CacheVector::const_iterator aIter
, aEnd
;
464 for (aIter
= aExport
.begin(), aEnd
= aExport
.end(); aIter
!= aEnd
; ++aIter
)
466 if ( aIter
->sMediaType
.equalsIgnoreAsciiCase( rMediaType
) )
467 return sal::static_int_cast
< sal_uInt16
>(aIter
- aExport
.begin());
469 return GRFILTER_FORMAT_NOTFOUND
;
472 sal_uInt16
FilterConfigCache::GetExportFormatNumberForShortName( const OUString
& rShortName
)
474 CacheVector::const_iterator aEnd
;
475 CacheVector::iterator aIter
;
476 for (aIter
= aExport
.begin(), aEnd
= aExport
.end(); aIter
!= aEnd
; ++aIter
)
478 if ( aIter
->GetShortName().equalsIgnoreAsciiCase( rShortName
) )
479 return sal::static_int_cast
< sal_uInt16
>(aIter
- aExport
.begin());
481 return GRFILTER_FORMAT_NOTFOUND
;
484 sal_uInt16
FilterConfigCache::GetExportFormatNumberForTypeName( const OUString
& rType
)
486 CacheVector::const_iterator aIter
, aEnd
;
487 for (aIter
= aExport
.begin(), aEnd
= aExport
.end(); aIter
!= aEnd
; ++aIter
)
489 if ( aIter
->sType
.equalsIgnoreAsciiCase( rType
) )
490 return sal::static_int_cast
< sal_uInt16
>(aIter
- aExport
.begin());
492 return GRFILTER_FORMAT_NOTFOUND
;
495 OUString
FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat
)
497 if( nFormat
< aExport
.size() )
498 return aExport
[ nFormat
].sUIName
;
502 OUString
FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat
)
504 if( nFormat
< aExport
.size() )
505 return aExport
[ nFormat
].sMediaType
;
509 OUString
FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat
)
511 if( nFormat
< aExport
.size() )
512 return aExport
[ nFormat
].GetShortName();
516 OUString
FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
518 if ( (nFormat
< aExport
.size()) && (nEntry
< aExport
[ nFormat
].lExtensionList
.getLength()) )
519 return aExport
[ nFormat
].lExtensionList
[ nEntry
];
523 OUString
FilterConfigCache::GetExportFilterTypeName( sal_uInt16 nFormat
)
525 if( nFormat
< aExport
.size() )
526 return aExport
[ nFormat
].sFilterType
;
530 OUString
FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat
)
532 if( nFormat
< aExport
.size() )
533 return aExport
[ nFormat
].sInternalFilterName
;
537 OUString
FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
539 OUString
aWildcard( GetExportFormatExtension( nFormat
, nEntry
) );
540 if ( !aWildcard
.isEmpty() )
541 aWildcard
= aWildcard
.replaceAt( 0, 0, "*." );
545 bool FilterConfigCache::IsExportInternalFilter( sal_uInt16 nFormat
)
547 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bIsInternalFilter
;
550 bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat
)
552 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bIsPixelFormat
;
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */