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 <o3tl/safeint.hxx>
23 #include <vcl/graphicfilter.hxx>
24 #include <unotools/configmgr.hxx>
25 #include <tools/svlibrary.h>
26 #include <com/sun/star/uno/Any.h>
27 #include <comphelper/processfactory.hxx>
28 #include <comphelper/sequence.hxx>
29 #include <com/sun/star/uno/Exception.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/configuration/theDefaultProvider.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
36 using namespace ::com::sun::star::lang
; // XMultiServiceFactory
37 using namespace ::com::sun::star::container
; // XNameAccess
38 using namespace ::com::sun::star::uno
; // Reference
39 using namespace ::com::sun::star::beans
; // PropertyValue
40 using namespace ::com::sun::star::configuration
;
42 const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList
[] =
44 IMP_BMP
, IMP_GIF
, IMP_PNG
, IMP_JPEG
, IMP_TIFF
,
45 IMP_XBM
, IMP_XPM
, IMP_TGA
, IMP_PICT
, IMP_MET
, IMP_RAS
,
46 IMP_PCX
, IMP_MOV
, IMP_PSD
, IMP_PCD
, IMP_PBM
, IMP_DXF
,
47 EXP_BMP
, EXP_GIF
, EXP_PNG
, EXP_JPEG
, EXP_TIFF
,
51 void FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString
& rUserDataEntry
)
53 bIsPixelFormat
= false;
54 sFilterName
= rUserDataEntry
;
56 for ( pPtr
= InternalPixelFilterNameList
; *pPtr
; pPtr
++ )
58 if ( sFilterName
.equalsIgnoreAsciiCaseAscii( *pPtr
) )
60 bIsPixelFormat
= true;
65 OUString
FilterConfigCache::FilterConfigCacheEntry::GetShortName()
68 if ( !lExtensionList
.empty() )
70 aShortName
= lExtensionList
[ 0 ];
71 if ( aShortName
.startsWith( "*." ) )
72 aShortName
= aShortName
.replaceAt( 0, 2, "" );
77 /** helper to open the configuration root of the underlying
81 specify, which config package should be opened.
82 Must be one of "types" or "filters"
84 @return A valid object if open was successful. The access on opened
85 data will be readonly. It returns NULL in case open failed.
87 @throws It let pass RuntimeExceptions only.
89 static Reference
< XInterface
> openConfig(const char* sPackage
)
91 Reference
< XComponentContext
> xContext(
92 comphelper::getProcessComponentContext() );
93 Reference
< XInterface
> xCfg
;
96 // get access to config API (not to file!)
97 Reference
< XMultiServiceFactory
> xConfigProvider
= theDefaultProvider::get( xContext
);
99 Sequence
< Any
> lParams(1);
100 PropertyValue aParam
;
102 // define cfg path for open
103 aParam
.Name
= "nodepath";
104 if (rtl_str_compareIgnoreAsciiCase(sPackage
, "types") == 0)
105 aParam
.Value
<<= OUString( "/org.openoffice.TypeDetection.Types/Types" );
106 if (rtl_str_compareIgnoreAsciiCase(sPackage
, "filters") == 0)
107 aParam
.Value
<<= OUString( "/org.openoffice.TypeDetection.GraphicFilter/Filters" );
108 lParams
[0] <<= aParam
;
110 // get access to file
111 xCfg
= xConfigProvider
->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", lParams
);
113 catch(const RuntimeException
&)
115 catch(const Exception
&)
121 void FilterConfigCache::ImplInit()
123 OUString
const STYPE ( "Type" );
124 OUString
const SUINAME ( "UIName" );
125 OUString
const SFLAGS ( "Flags" );
126 OUString
const SMEDIATYPE ( "MediaType" );
127 OUString
const SEXTENSIONS ( "Extensions" );
128 OUString
const SFORMATNAME ( "FormatName" );
129 OUString
const SREALFILTERNAME ( "RealFilterName" );
131 // get access to config
132 Reference
< XNameAccess
> xTypeAccess ( openConfig("types" ), UNO_QUERY
);
133 Reference
< XNameAccess
> xFilterAccess( openConfig("filters"), UNO_QUERY
);
135 if ( !(xTypeAccess
.is() && xFilterAccess
.is()) )
138 const Sequence
< OUString
> lAllFilter
= xFilterAccess
->getElementNames();
140 for ( const OUString
& sInternalFilterName
: lAllFilter
)
142 Reference
< XPropertySet
> xFilterSet
;
143 xFilterAccess
->getByName( sInternalFilterName
) >>= xFilterSet
;
144 if (!xFilterSet
.is())
147 FilterConfigCacheEntry aEntry
;
149 aEntry
.sInternalFilterName
= sInternalFilterName
;
150 xFilterSet
->getPropertyValue(STYPE
) >>= aEntry
.sType
;
151 xFilterSet
->getPropertyValue(SUINAME
) >>= aEntry
.sUIName
;
152 xFilterSet
->getPropertyValue(SREALFILTERNAME
) >>= aEntry
.sFilterType
;
153 Sequence
< OUString
> lFlags
;
154 xFilterSet
->getPropertyValue(SFLAGS
) >>= lFlags
;
155 if (lFlags
.getLength()!=1 || lFlags
[0].isEmpty())
157 if (lFlags
[0].equalsIgnoreAsciiCase("import"))
159 else if (lFlags
[0].equalsIgnoreAsciiCase("export"))
162 OUString sFormatName
;
163 xFilterSet
->getPropertyValue(SFORMATNAME
) >>= sFormatName
;
164 aEntry
.CreateFilterName( sFormatName
);
166 Reference
< XPropertySet
> xTypeSet
;
167 xTypeAccess
->getByName( aEntry
.sType
) >>= xTypeSet
;
171 xTypeSet
->getPropertyValue(SMEDIATYPE
) >>= aEntry
.sMediaType
;
172 css::uno::Sequence
<OUString
> tmp
;
173 if (xTypeSet
->getPropertyValue(SEXTENSIONS
) >>= tmp
)
174 aEntry
.lExtensionList
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(tmp
);
176 // The first extension will be used
177 // to generate our internal FilterType ( BMP, WMF ... )
178 OUString
aExtension( aEntry
.GetShortName() );
179 if (aExtension
.getLength() != 3)
182 if ( aEntry
.nFlags
& 1 )
183 aImport
.push_back( aEntry
);
184 if ( aEntry
.nFlags
& 2 )
185 aExport
.push_back( aEntry
);
187 // bFilterEntryCreated!?
188 if (!( aEntry
.nFlags
& 3 ))
189 continue; //? Entry was already inserted ... but following code will be suppressed?!
193 const char* FilterConfigCache::InternalFilterListForSvxLight
[] =
217 "svm","1","SVMETAFILE",
218 "svm","2","SVMETAFILE",
233 void FilterConfigCache::ImplInitSmart()
236 for ( pPtr
= InternalFilterListForSvxLight
; *pPtr
; pPtr
++ )
238 FilterConfigCacheEntry aEntry
;
240 OUString
sExtension( OUString::createFromAscii( *pPtr
++ ) );
242 aEntry
.lExtensionList
.push_back(sExtension
);
244 aEntry
.sType
= sExtension
;
245 aEntry
.sUIName
= sExtension
;
247 OString
sFlags( *pPtr
++ );
248 aEntry
.nFlags
= sFlags
.toInt32();
250 OUString
sUserData( OUString::createFromAscii( *pPtr
) );
251 aEntry
.CreateFilterName( sUserData
);
253 if ( aEntry
.nFlags
& 1 )
254 aImport
.push_back( aEntry
);
255 if ( aEntry
.nFlags
& 2 )
256 aExport
.push_back( aEntry
);
260 FilterConfigCache::FilterConfigCache( bool bConfig
)
263 bConfig
= !utl::ConfigManager::IsFuzzing();
270 FilterConfigCache::~FilterConfigCache()
274 OUString
FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat
)
276 if( nFormat
< aImport
.size() )
277 return aImport
[ nFormat
].sFilterName
;
281 sal_uInt16
FilterConfigCache::GetImportFormatNumber( std::u16string_view rFormatName
)
284 for (auto const& elem
: aImport
)
286 if ( elem
.sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
290 return GRFILTER_FORMAT_NOTFOUND
;
293 /// get the index of the filter that matches this extension
294 sal_uInt16
FilterConfigCache::GetImportFormatNumberForExtension( std::u16string_view rExt
)
297 for (auto const& elem
: aImport
)
299 for ( OUString
const & s
: elem
.lExtensionList
)
301 if ( s
.equalsIgnoreAsciiCase( rExt
) )
306 return GRFILTER_FORMAT_NOTFOUND
;
309 sal_uInt16
FilterConfigCache::GetImportFormatNumberForShortName( std::u16string_view rShortName
)
312 for (auto & elem
: aImport
)
314 if ( elem
.GetShortName().equalsIgnoreAsciiCase( rShortName
) )
318 return GRFILTER_FORMAT_NOTFOUND
;
321 sal_uInt16
FilterConfigCache::GetImportFormatNumberForTypeName( std::u16string_view rType
)
324 for (auto const& elem
: aImport
)
326 if ( elem
.sType
.equalsIgnoreAsciiCase( rType
) )
330 return GRFILTER_FORMAT_NOTFOUND
;
333 OUString
FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat
)
335 if( nFormat
< aImport
.size() )
336 return aImport
[ nFormat
].sUIName
;
340 OUString
FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat
)
342 if( nFormat
< aImport
.size() )
343 return aImport
[ nFormat
].sMediaType
;
347 OUString
FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat
)
349 if( nFormat
< aImport
.size() )
350 return aImport
[ nFormat
].GetShortName();
354 OUString
FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
356 if ( (nFormat
< aImport
.size()) && (o3tl::make_unsigned(nEntry
) < aImport
[ nFormat
].lExtensionList
.size()) )
357 return aImport
[ nFormat
].lExtensionList
[ nEntry
];
361 OUString
FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat
)
363 if( nFormat
< aImport
.size() )
364 return aImport
[ nFormat
].sType
;
368 OUString
FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat
)
370 if( nFormat
< aImport
.size() )
371 return aImport
[ nFormat
].sFilterType
;
375 OUString
FilterConfigCache::GetImportWildcard(sal_uInt16 nFormat
, sal_Int32 nEntry
)
377 OUString
aWildcard( GetImportFormatExtension( nFormat
, nEntry
) );
378 if ( !aWildcard
.isEmpty() )
379 aWildcard
= aWildcard
.replaceAt( 0, 0, "*." );
383 OUString
FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat
)
385 if( nFormat
< aExport
.size() )
386 return aExport
[ nFormat
].sFilterName
;
390 sal_uInt16
FilterConfigCache::GetExportFormatNumber(std::u16string_view rFormatName
)
393 for (auto const& elem
: aExport
)
395 if ( elem
.sUIName
.equalsIgnoreAsciiCase( rFormatName
) )
399 return GRFILTER_FORMAT_NOTFOUND
;
402 sal_uInt16
FilterConfigCache::GetExportFormatNumberForMediaType( std::u16string_view rMediaType
)
405 for (auto const& elem
: aExport
)
407 if ( elem
.sMediaType
.equalsIgnoreAsciiCase( rMediaType
) )
411 return GRFILTER_FORMAT_NOTFOUND
;
414 sal_uInt16
FilterConfigCache::GetExportFormatNumberForShortName( std::u16string_view rShortName
)
417 for (auto & elem
: aExport
)
419 if ( elem
.GetShortName().equalsIgnoreAsciiCase( rShortName
) )
423 return GRFILTER_FORMAT_NOTFOUND
;
426 sal_uInt16
FilterConfigCache::GetExportFormatNumberForTypeName( std::u16string_view rType
)
429 for (auto const& elem
: aExport
)
431 if ( elem
.sType
.equalsIgnoreAsciiCase( rType
) )
435 return GRFILTER_FORMAT_NOTFOUND
;
438 OUString
FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat
)
440 if( nFormat
< aExport
.size() )
441 return aExport
[ nFormat
].sUIName
;
445 OUString
FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat
)
447 if( nFormat
< aExport
.size() )
448 return aExport
[ nFormat
].sMediaType
;
452 OUString
FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat
)
454 if( nFormat
< aExport
.size() )
455 return aExport
[ nFormat
].GetShortName();
459 OUString
FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat
, sal_Int32 nEntry
)
461 if ( (nFormat
< aExport
.size()) && (o3tl::make_unsigned(nEntry
) < aExport
[ nFormat
].lExtensionList
.size()) )
462 return aExport
[ nFormat
].lExtensionList
[ nEntry
];
466 OUString
FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat
)
468 if( nFormat
< aExport
.size() )
469 return aExport
[ nFormat
].sInternalFilterName
;
473 OUString
FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat
, sal_Int32 nEntry
)
475 OUString
aWildcard( GetExportFormatExtension( nFormat
, nEntry
) );
476 if ( !aWildcard
.isEmpty() )
477 aWildcard
= aWildcard
.replaceAt( 0, 0, "*." );
481 bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat
)
483 return (nFormat
< aExport
.size()) && aExport
[ nFormat
].bIsPixelFormat
;
486 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */