LibreOffice Module vcl (master)  1
FilterConfigCache.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "FilterConfigCache.hxx"
21 
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>
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>
35 
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 ;
41 
43 {
48  nullptr
49 };
50 
52 {
53  bIsPixelFormat = false;
54  sFilterName = rUserDataEntry;
55  const char** pPtr;
56  for ( pPtr = InternalPixelFilterNameList; *pPtr; pPtr++ )
57  {
58  if ( sFilterName.equalsIgnoreAsciiCaseAscii( *pPtr ) )
59  {
60  bIsPixelFormat = true;
61  }
62  }
63 }
64 
66 {
67  OUString aShortName;
68  if ( !lExtensionList.empty() )
69  {
70  aShortName = lExtensionList[ 0 ];
71  if ( aShortName.startsWith( "*." ) )
72  aShortName = aShortName.replaceAt( 0, 2, "" );
73  }
74  return aShortName;
75 }
76 
89 static Reference< XInterface > openConfig(const char* sPackage)
90 {
93  Reference< XInterface > xCfg;
94  try
95  {
96  // get access to config API (not to file!)
97  Reference< XMultiServiceFactory > xConfigProvider = theDefaultProvider::get( xContext );
98 
99  Sequence< Any > lParams(1);
100  PropertyValue aParam ;
101 
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;
109 
110  // get access to file
111  xCfg = xConfigProvider->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", lParams);
112  }
113  catch(const RuntimeException&)
114  { throw; }
115  catch(const Exception&)
116  { xCfg.clear(); }
117 
118  return xCfg;
119 }
120 
122 {
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" );
130 
131  // get access to config
132  Reference< XNameAccess > xTypeAccess ( openConfig("types" ), UNO_QUERY );
133  Reference< XNameAccess > xFilterAccess( openConfig("filters"), UNO_QUERY );
134 
135  if ( !(xTypeAccess.is() && xFilterAccess.is()) )
136  return;
137 
138  const Sequence< OUString > lAllFilter = xFilterAccess->getElementNames();
139 
140  for ( const OUString& sInternalFilterName : lAllFilter )
141  {
142  Reference< XPropertySet > xFilterSet;
143  xFilterAccess->getByName( sInternalFilterName ) >>= xFilterSet;
144  if (!xFilterSet.is())
145  continue;
146 
147  FilterConfigCacheEntry aEntry;
148 
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())
156  continue;
157  if (lFlags[0].equalsIgnoreAsciiCase("import"))
158  aEntry.nFlags = 1;
159  else if (lFlags[0].equalsIgnoreAsciiCase("export"))
160  aEntry.nFlags = 2;
161 
162  OUString sFormatName;
163  xFilterSet->getPropertyValue(SFORMATNAME) >>= sFormatName;
164  aEntry.CreateFilterName( sFormatName );
165 
166  Reference< XPropertySet > xTypeSet;
167  xTypeAccess->getByName( aEntry.sType ) >>= xTypeSet;
168  if (!xTypeSet.is())
169  continue;
170 
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);
175 
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)
180  continue;
181 
182  if ( aEntry.nFlags & 1 )
183  aImport.push_back( aEntry );
184  if ( aEntry.nFlags & 2 )
185  aExport.push_back( aEntry );
186 
187  // bFilterEntryCreated!?
188  if (!( aEntry.nFlags & 3 ))
189  continue; //? Entry was already inserted ... but following code will be suppressed?!
190  }
191 };
192 
194 {
195  "bmp","1","SVBMP",
196  "bmp","2","SVBMP",
197  "dxf","1","SVDXF",
198  "eps","1","SVIEPS",
199  "eps","2","SVEEPS",
200  "gif","1","SVIGIF",
201  "gif","2","SVEGIF",
202  "jpg","1","SVIJPEG",
203  "jpg","2","SVEJPEG",
204  "mov","1","SVMOV",
205  "mov","2","SVMOV",
206  "met","1","SVMET",
207  "png","1","SVIPNG",
208  "png","2","SVEPNG",
209  "pct","1","SVPICT",
210  "pcd","1","SVPCD",
211  "psd","1","SVPSD",
212  "pcx","1","SVPCX",
213  "pbm","1","SVPBM",
214  "pgm","1","SVPBM",
215  "ppm","1","SVPBM",
216  "ras","1","SVRAS",
217  "svm","1","SVMETAFILE",
218  "svm","2","SVMETAFILE",
219  "tga","1","SVTGA",
220  "tif","1","SVTIFF",
221  "tif","2","SVTIFF",
222  "emf","1","SVEMF",
223  "emf","2","SVEMF",
224  "wmf","1","SVWMF",
225  "wmf","2","SVWMF",
226  "xbm","1","SVIXBM",
227  "xpm","1","SVIXPM",
228  "svg","1","SVISVG",
229  "svg","2","SVESVG",
230  nullptr
231 };
232 
234 {
235  const char** pPtr;
236  for ( pPtr = InternalFilterListForSvxLight; *pPtr; pPtr++ )
237  {
238  FilterConfigCacheEntry aEntry;
239 
240  OUString sExtension( OUString::createFromAscii( *pPtr++ ) );
241 
242  aEntry.lExtensionList.push_back(sExtension);
243 
244  aEntry.sType = sExtension;
245  aEntry.sUIName = sExtension;
246 
247  OString sFlags( *pPtr++ );
248  aEntry.nFlags = sFlags.toInt32();
249 
250  OUString sUserData( OUString::createFromAscii( *pPtr ) );
251  aEntry.CreateFilterName( sUserData );
252 
253  if ( aEntry.nFlags & 1 )
254  aImport.push_back( aEntry );
255  if ( aEntry.nFlags & 2 )
256  aExport.push_back( aEntry );
257  }
258 }
259 
261 {
262  if (bConfig)
263  bConfig = !utl::ConfigManager::IsFuzzing();
264  if (bConfig)
265  ImplInit();
266  else
267  ImplInitSmart();
268 }
269 
271 {
272 }
273 
274 OUString FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat )
275 {
276  if( nFormat < aImport.size() )
277  return aImport[ nFormat ].sFilterName;
278  return OUString();
279 }
280 
281 sal_uInt16 FilterConfigCache::GetImportFormatNumber( std::u16string_view rFormatName )
282 {
283  sal_uInt16 nPos = 0;
284  for (auto const& elem : aImport)
285  {
286  if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
287  return nPos;
288  ++nPos;
289  }
291 }
292 
294 sal_uInt16 FilterConfigCache::GetImportFormatNumberForExtension( std::u16string_view rExt )
295 {
296  sal_uInt16 nPos = 0;
297  for (auto const& elem : aImport)
298  {
299  for ( OUString const & s : elem.lExtensionList )
300  {
301  if ( s.equalsIgnoreAsciiCase( rExt ) )
302  return nPos;
303  }
304  ++nPos;
305  }
307 }
308 
309 sal_uInt16 FilterConfigCache::GetImportFormatNumberForShortName( std::u16string_view rShortName )
310 {
311  sal_uInt16 nPos = 0;
312  for (auto & elem : aImport)
313  {
314  if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
315  return nPos;
316  ++nPos;
317  }
319 }
320 
321 sal_uInt16 FilterConfigCache::GetImportFormatNumberForTypeName( std::u16string_view rType )
322 {
323  sal_uInt16 nPos = 0;
324  for (auto const& elem : aImport)
325  {
326  if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
327  return nPos;
328  ++nPos;
329  }
331 }
332 
333 OUString FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat )
334 {
335  if( nFormat < aImport.size() )
336  return aImport[ nFormat ].sUIName;
337  return OUString();
338 }
339 
340 OUString FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat )
341 {
342  if( nFormat < aImport.size() )
343  return aImport[ nFormat ].sMediaType;
344  return OUString();
345 }
346 
347 OUString FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat )
348 {
349  if( nFormat < aImport.size() )
350  return aImport[ nFormat ].GetShortName();
351  return OUString();
352 }
353 
354 OUString FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
355 {
356  if ( (nFormat < aImport.size()) && (o3tl::make_unsigned(nEntry) < aImport[ nFormat ].lExtensionList.size()) )
357  return aImport[ nFormat ].lExtensionList[ nEntry ];
358  return OUString();
359 }
360 
361 OUString FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat )
362 {
363  if( nFormat < aImport.size() )
364  return aImport[ nFormat ].sType;
365  return OUString();
366 }
367 
368 OUString FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat )
369 {
370  if( nFormat < aImport.size() )
371  return aImport[ nFormat ].sFilterType;
372  return OUString();
373 }
374 
375 OUString FilterConfigCache::GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
376 {
377  OUString aWildcard( GetImportFormatExtension( nFormat, nEntry ) );
378  if ( !aWildcard.isEmpty() )
379  aWildcard = aWildcard.replaceAt( 0, 0, "*." );
380  return aWildcard;
381 }
382 
383 OUString FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat )
384 {
385  if( nFormat < aExport.size() )
386  return aExport[ nFormat ].sFilterName;
387  return OUString();
388 }
389 
390 sal_uInt16 FilterConfigCache::GetExportFormatNumber(std::u16string_view rFormatName)
391 {
392  sal_uInt16 nPos = 0;
393  for (auto const& elem : aExport)
394  {
395  if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
396  return nPos;
397  ++nPos;
398  }
400 }
401 
402 sal_uInt16 FilterConfigCache::GetExportFormatNumberForMediaType( std::u16string_view rMediaType )
403 {
404  sal_uInt16 nPos = 0;
405  for (auto const& elem : aExport)
406  {
407  if ( elem.sMediaType.equalsIgnoreAsciiCase( rMediaType ) )
408  return nPos;
409  ++nPos;
410  }
412 }
413 
414 sal_uInt16 FilterConfigCache::GetExportFormatNumberForShortName( std::u16string_view rShortName )
415 {
416  sal_uInt16 nPos = 0;
417  for (auto & elem : aExport)
418  {
419  if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
420  return nPos;
421  ++nPos;
422  }
424 }
425 
426 sal_uInt16 FilterConfigCache::GetExportFormatNumberForTypeName( std::u16string_view rType )
427 {
428  sal_uInt16 nPos = 0;
429  for (auto const& elem : aExport)
430  {
431  if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
432  return nPos;
433  ++nPos;
434  }
436 }
437 
438 OUString FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat )
439 {
440  if( nFormat < aExport.size() )
441  return aExport[ nFormat ].sUIName;
442  return OUString();
443 }
444 
445 OUString FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat )
446 {
447  if( nFormat < aExport.size() )
448  return aExport[ nFormat ].sMediaType;
449  return OUString();
450 }
451 
452 OUString FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat )
453 {
454  if( nFormat < aExport.size() )
455  return aExport[ nFormat ].GetShortName();
456  return OUString();
457 }
458 
459 OUString FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
460 {
461  if ( (nFormat < aExport.size()) && (o3tl::make_unsigned(nEntry) < aExport[ nFormat ].lExtensionList.size()) )
462  return aExport[ nFormat ].lExtensionList[ nEntry ];
463  return OUString();
464 }
465 
467 {
468  if( nFormat < aExport.size() )
469  return aExport[ nFormat ].sInternalFilterName;
470  return OUString();
471 }
472 
473 OUString FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
474 {
475  OUString aWildcard( GetExportFormatExtension( nFormat, nEntry ) );
476  if ( !aWildcard.isEmpty() )
477  aWildcard = aWildcard.replaceAt( 0, 0, "*." );
478  return aWildcard;
479 }
480 
481 bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat )
482 {
483  return (nFormat < aExport.size()) && aExport[ nFormat ].bIsPixelFormat;
484 }
485 
486 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString GetImportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define IMP_MOV
OUString GetExportFormatName(sal_uInt16 nFormat)
sal_uInt16 GetImportFormatNumberForTypeName(std::u16string_view rType)
OUString GetImportFilterName(sal_uInt16 nFormat)
sal_uInt16 GetExportFormatNumberForTypeName(std::u16string_view rType)
#define IMP_PICT
sal_uInt16 GetImportFormatNumberForExtension(std::u16string_view rExt)
get the index of the filter that matches this extension
OUString GetExportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define EXP_GIF
#define IMP_JPEG
OUString GetExportInternalFilterName(sal_uInt16 nFormat)
#define EXP_JPEG
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
sal_uInt16 GetImportFormatNumberForShortName(std::u16string_view rShortName)
#define IMP_PCD
#define EXP_TIFF
OUString GetImportFilterType(sal_uInt16 nFormat)
static bool IsFuzzing()
#define IMP_DXF
bool IsExportPixelFormat(sal_uInt16 nFormat)
OUString GetImportFormatShortName(sal_uInt16 nFormat)
OUString GetExportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
std::vector< FilterConfigCacheEntry > aExport
FilterConfigCache(bool bUseConfig)
#define IMP_RAS
#define IMP_BMP
OUString GetImportFormatMediaType(sal_uInt16 nFormat)
OptionalString sType
#define IMP_PBM
sal_uInt16 GetExportFormatNumber(std::u16string_view rFormatName)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
#define IMP_XBM
OUString GetImportFilterTypeName(sal_uInt16 nFormat)
#define IMP_PSD
#define IMP_TIFF
sal_uInt16 GetImportFormatNumber(std::u16string_view rFormatName)
OUString GetImportFormatName(sal_uInt16 nFormat)
#define IMP_MET
void CreateFilterName(const OUString &rUserDataEntry)
OUString GetExportFormatMediaType(sal_uInt16 nFormat)
constexpr OUStringLiteral sMediaType
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
#define IMP_PNG
#define IMP_PCX
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
#define IMP_GIF
std::vector< FilterConfigCacheEntry > aImport
Reference< XComponentContext > getProcessComponentContext()
OUString aWildcard
OUString GetExportFilterName(sal_uInt16 nFormat)
#define IMP_XPM
sal_uInt16 GetExportFormatNumberForMediaType(std::u16string_view rMediaType)
static Reference< XInterface > openConfig(const char *sPackage)
helper to open the configuration root of the underlying config package
#define EXP_BMP
OUString GetExportFormatShortName(sal_uInt16 nFormat)
#define IMP_TGA
sal_uInt16 GetExportFormatNumberForShortName(std::u16string_view rShortName)
static const char * InternalFilterListForSvxLight[]
sal_uInt16 nPos
OUString GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
#define GRFILTER_FORMAT_NOTFOUND
#define EXP_PNG