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 {
45  EXP_BMP, EXP_JPEG, EXP_PNG, IMP_MOV, nullptr
46 };
47 
49 {
52 };
53 
55 {
56  "egi", "icd", "ipd", "ipx", "ipb", "epb", "epg",
57  "epp", "ira", "era", "itg", "iti", "eti", "exp", nullptr
58 };
59 
61 {
63  sFilterName = rUserDataEntry;
64  const char** pPtr;
65  for ( pPtr = InternalPixelFilterNameList; *pPtr && !bIsInternalFilter; pPtr++ )
66  {
67  if ( sFilterName.equalsIgnoreAsciiCaseAscii( *pPtr ) )
68  {
69  bIsInternalFilter = true;
70  bIsPixelFormat = true;
71  }
72  }
73  for ( pPtr = InternalVectorFilterNameList; *pPtr && !bIsInternalFilter; pPtr++ )
74  {
75  if ( sFilterName.equalsIgnoreAsciiCaseAscii( *pPtr ) )
76  bIsInternalFilter = true;
77  }
78  if ( !bIsInternalFilter )
79  {
80  for ( pPtr = ExternalPixelFilterNameList; *pPtr && !bIsPixelFormat; pPtr++ )
81  {
82  if ( sFilterName.equalsIgnoreAsciiCaseAscii( *pPtr ) )
83  bIsPixelFormat = true;
84  }
86  sFilterName = SVLIBRARY("gie");
87  }
88 }
89 
91 {
92  OUString aShortName;
93  if ( !lExtensionList.empty() )
94  {
95  aShortName = lExtensionList[ 0 ];
96  if ( aShortName.startsWith( "*." ) )
97  aShortName = aShortName.replaceAt( 0, 2, "" );
98  }
99  return aShortName;
100 }
101 
114 static Reference< XInterface > openConfig(const char* sPackage)
115 {
119  try
120  {
121  // get access to config API (not to file!)
122  Reference< XMultiServiceFactory > xConfigProvider = theDefaultProvider::get( xContext );
123 
124  Sequence< Any > lParams(1);
125  PropertyValue aParam ;
126 
127  // define cfg path for open
128  aParam.Name = "nodepath";
129  if (rtl_str_compareIgnoreAsciiCase(sPackage, "types") == 0)
130  aParam.Value <<= OUString( "/org.openoffice.TypeDetection.Types/Types" );
131  if (rtl_str_compareIgnoreAsciiCase(sPackage, "filters") == 0)
132  aParam.Value <<= OUString( "/org.openoffice.TypeDetection.GraphicFilter/Filters" );
133  lParams[0] <<= aParam;
134 
135  // get access to file
136  xCfg = xConfigProvider->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", lParams);
137  }
138  catch(const RuntimeException&)
139  { throw; }
140  catch(const Exception&)
141  { xCfg.clear(); }
142 
143  return xCfg;
144 }
145 
147 {
148  OUString const STYPE ( "Type" );
149  OUString const SUINAME ( "UIName" );
150  OUString const SFLAGS ( "Flags" );
151  OUString const SMEDIATYPE ( "MediaType" );
152  OUString const SEXTENSIONS ( "Extensions" );
153  OUString const SFORMATNAME ( "FormatName" );
154  OUString const SREALFILTERNAME ( "RealFilterName" );
155 
156  // get access to config
157  Reference< XNameAccess > xTypeAccess ( openConfig("types" ), UNO_QUERY );
158  Reference< XNameAccess > xFilterAccess( openConfig("filters"), UNO_QUERY );
159 
160  if ( !(xTypeAccess.is() && xFilterAccess.is()) )
161  return;
162 
163  const Sequence< OUString > lAllFilter = xFilterAccess->getElementNames();
164 
165  for ( const OUString& sInternalFilterName : lAllFilter )
166  {
167  Reference< XPropertySet > xFilterSet;
168  xFilterAccess->getByName( sInternalFilterName ) >>= xFilterSet;
169  if (!xFilterSet.is())
170  continue;
171 
172  FilterConfigCacheEntry aEntry;
173 
174  aEntry.sInternalFilterName = sInternalFilterName;
175  xFilterSet->getPropertyValue(STYPE) >>= aEntry.sType;
176  xFilterSet->getPropertyValue(SUINAME) >>= aEntry.sUIName;
177  xFilterSet->getPropertyValue(SREALFILTERNAME) >>= aEntry.sFilterType;
178  Sequence< OUString > lFlags;
179  xFilterSet->getPropertyValue(SFLAGS) >>= lFlags;
180  if (lFlags.getLength()!=1 || lFlags[0].isEmpty())
181  continue;
182  if (lFlags[0].equalsIgnoreAsciiCase("import"))
183  aEntry.nFlags = 1;
184  else if (lFlags[0].equalsIgnoreAsciiCase("export"))
185  aEntry.nFlags = 2;
186 
187  OUString sFormatName;
188  xFilterSet->getPropertyValue(SFORMATNAME) >>= sFormatName;
189  aEntry.CreateFilterName( sFormatName );
190 
191  Reference< XPropertySet > xTypeSet;
192  xTypeAccess->getByName( aEntry.sType ) >>= xTypeSet;
193  if (!xTypeSet.is())
194  continue;
195 
196  xTypeSet->getPropertyValue(SMEDIATYPE) >>= aEntry.sMediaType;
197  css::uno::Sequence<OUString> tmp;
198  if (xTypeSet->getPropertyValue(SEXTENSIONS) >>= tmp)
199  aEntry.lExtensionList = comphelper::sequenceToContainer<std::vector<OUString>>(tmp);
200 
201  // The first extension will be used
202  // to generate our internal FilterType ( BMP, WMF ... )
203  OUString aExtension( aEntry.GetShortName() );
204  if (aExtension.getLength() != 3)
205  continue;
206 
207  if ( aEntry.nFlags & 1 )
208  aImport.push_back( aEntry );
209  if ( aEntry.nFlags & 2 )
210  aExport.push_back( aEntry );
211 
212  // bFilterEntryCreated!?
213  if (!( aEntry.nFlags & 3 ))
214  continue; //? Entry was already inserted ... but following code will be suppressed?!
215  }
216 };
217 
219 {
220  "bmp","1","SVBMP",
221  "bmp","2","SVBMP",
222  "dxf","1","idx",
223  "eps","1","ips",
224  "eps","2","eps",
225  "gif","1","SVIGIF",
226  "gif","2","egi",
227  "jpg","1","SVIJPEG",
228  "jpg","2","SVEJPEG",
229  "mov","1","SVMOV",
230  "mov","2","SVMOV",
231  "met","1","ime",
232  "png","1","SVIPNG",
233  "png","2","SVEPNG",
234  "pct","1","ipt",
235  "pct","2","ept",
236  "pcd","1","icd",
237  "psd","1","ipd",
238  "pcx","1","ipx",
239  "pbm","1","ipb",
240  "pgm","1","ipb",
241  "ppm","1","ipb",
242  "ras","1","ira",
243  "ras","2","era",
244  "svm","1","SVMETAFILE",
245  "svm","2","SVMETAFILE",
246  "tga","1","itg",
247  "tif","1","iti",
248  "tif","2","eti",
249  "emf","1","SVEMF",
250  "emf","2","SVEMF",
251  "wmf","1","SVWMF",
252  "wmf","2","SVWMF",
253  "xbm","1","SVIXBM",
254  "xpm","1","SVIXPM",
255  "xpm","2","exp",
256  "svg","1","SVISVG",
257  "svg","2","SVESVG",
258  nullptr
259 };
260 
262 {
263  const char** pPtr;
264  for ( pPtr = InternalFilterListForSvxLight; *pPtr; pPtr++ )
265  {
266  FilterConfigCacheEntry aEntry;
267 
268  OUString sExtension( OUString::createFromAscii( *pPtr++ ) );
269 
270  aEntry.lExtensionList.push_back(sExtension);
271 
272  aEntry.sType = sExtension;
273  aEntry.sUIName = sExtension;
274 
275  OString sFlags( *pPtr++ );
276  aEntry.nFlags = sFlags.toInt32();
277 
278  OUString sUserData( OUString::createFromAscii( *pPtr ) );
279  aEntry.CreateFilterName( sUserData );
280 
281  if ( aEntry.nFlags & 1 )
282  aImport.push_back( aEntry );
283  if ( aEntry.nFlags & 2 )
284  aExport.push_back( aEntry );
285  }
286 }
287 
289 {
290  if (bConfig)
291  bConfig = !utl::ConfigManager::IsFuzzing();
292  if (bConfig)
293  ImplInit();
294  else
295  ImplInitSmart();
296 }
297 
299 {
300 }
301 
302 OUString FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat )
303 {
304  if( nFormat < aImport.size() )
305  return aImport[ nFormat ].sFilterName;
306  return OUString();
307 }
308 
309 sal_uInt16 FilterConfigCache::GetImportFormatNumber( const OUString& rFormatName )
310 {
311  sal_uInt16 nPos = 0;
312  for (auto const& elem : aImport)
313  {
314  if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
315  return nPos;
316  ++nPos;
317  }
319 }
320 
323 {
324  sal_uInt16 nPos = 0;
325  for (auto const& elem : aImport)
326  {
327  for ( OUString const & s : elem.lExtensionList )
328  {
329  if ( s.equalsIgnoreAsciiCase( rExt ) )
330  return nPos;
331  }
332  ++nPos;
333  }
335 }
336 
337 sal_uInt16 FilterConfigCache::GetImportFormatNumberForShortName( const OUString& rShortName )
338 {
339  sal_uInt16 nPos = 0;
340  for (auto & elem : aImport)
341  {
342  if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
343  return nPos;
344  ++nPos;
345  }
347 }
348 
349 sal_uInt16 FilterConfigCache::GetImportFormatNumberForTypeName( const OUString& rType )
350 {
351  sal_uInt16 nPos = 0;
352  for (auto const& elem : aImport)
353  {
354  if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
355  return nPos;
356  ++nPos;
357  }
359 }
360 
361 OUString FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat )
362 {
363  if( nFormat < aImport.size() )
364  return aImport[ nFormat ].sUIName;
365  return OUString();
366 }
367 
368 OUString FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat )
369 {
370  if( nFormat < aImport.size() )
371  return aImport[ nFormat ].sMediaType;
372  return OUString();
373 }
374 
375 OUString FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat )
376 {
377  if( nFormat < aImport.size() )
378  return aImport[ nFormat ].GetShortName();
379  return OUString();
380 }
381 
382 OUString FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
383 {
384  if ( (nFormat < aImport.size()) && (o3tl::make_unsigned(nEntry) < aImport[ nFormat ].lExtensionList.size()) )
385  return aImport[ nFormat ].lExtensionList[ nEntry ];
386  return OUString();
387 }
388 
389 OUString FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat )
390 {
391  if( nFormat < aImport.size() )
392  return aImport[ nFormat ].sType;
393  return OUString();
394 }
395 
396 OUString FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat )
397 {
398  if( nFormat < aImport.size() )
399  return aImport[ nFormat ].sFilterType;
400  return OUString();
401 }
402 
403 OUString FilterConfigCache::GetExternalFilterName(sal_uInt16 nFormat, bool bExport)
404 {
405  if (bExport)
406  {
407  if (nFormat < aExport.size())
408  return aExport[nFormat].sExternalFilterName;
409  }
410  else
411  {
412  if (nFormat < aImport.size())
413  return aImport[nFormat].sExternalFilterName;
414  }
415  return OUString();
416 }
417 
418 OUString FilterConfigCache::GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
419 {
420  OUString aWildcard( GetImportFormatExtension( nFormat, nEntry ) );
421  if ( !aWildcard.isEmpty() )
422  aWildcard = aWildcard.replaceAt( 0, 0, "*." );
423  return aWildcard;
424 }
425 
427 {
428  return (nFormat < aImport.size()) && aImport[ nFormat ].bIsInternalFilter;
429 }
430 
431 OUString FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat )
432 {
433  if( nFormat < aExport.size() )
434  return aExport[ nFormat ].sFilterName;
435  return OUString();
436 }
437 
438 sal_uInt16 FilterConfigCache::GetExportFormatNumber(const OUString& rFormatName)
439 {
440  sal_uInt16 nPos = 0;
441  for (auto const& elem : aExport)
442  {
443  if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
444  return nPos;
445  ++nPos;
446  }
448 }
449 
450 sal_uInt16 FilterConfigCache::GetExportFormatNumberForMediaType( const OUString& rMediaType )
451 {
452  sal_uInt16 nPos = 0;
453  for (auto const& elem : aExport)
454  {
455  if ( elem.sMediaType.equalsIgnoreAsciiCase( rMediaType ) )
456  return nPos;
457  ++nPos;
458  }
460 }
461 
462 sal_uInt16 FilterConfigCache::GetExportFormatNumberForShortName( const OUString& rShortName )
463 {
464  sal_uInt16 nPos = 0;
465  for (auto & elem : aExport)
466  {
467  if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
468  return nPos;
469  ++nPos;
470  }
472 }
473 
474 sal_uInt16 FilterConfigCache::GetExportFormatNumberForTypeName( const OUString& rType )
475 {
476  sal_uInt16 nPos = 0;
477  for (auto const& elem : aExport)
478  {
479  if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
480  return nPos;
481  ++nPos;
482  }
484 }
485 
486 OUString FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat )
487 {
488  if( nFormat < aExport.size() )
489  return aExport[ nFormat ].sUIName;
490  return OUString();
491 }
492 
493 OUString FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat )
494 {
495  if( nFormat < aExport.size() )
496  return aExport[ nFormat ].sMediaType;
497  return OUString();
498 }
499 
500 OUString FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat )
501 {
502  if( nFormat < aExport.size() )
503  return aExport[ nFormat ].GetShortName();
504  return OUString();
505 }
506 
507 OUString FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
508 {
509  if ( (nFormat < aExport.size()) && (o3tl::make_unsigned(nEntry) < aExport[ nFormat ].lExtensionList.size()) )
510  return aExport[ nFormat ].lExtensionList[ nEntry ];
511  return OUString();
512 }
513 
515 {
516  if( nFormat < aExport.size() )
517  return aExport[ nFormat ].sInternalFilterName;
518  return OUString();
519 }
520 
521 OUString FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
522 {
523  OUString aWildcard( GetExportFormatExtension( nFormat, nEntry ) );
524  if ( !aWildcard.isEmpty() )
525  aWildcard = aWildcard.replaceAt( 0, 0, "*." );
526  return aWildcard;
527 }
528 
530 {
531  return (nFormat < aExport.size()) && aExport[ nFormat ].bIsInternalFilter;
532 }
533 
534 bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat )
535 {
536  return (nFormat < aExport.size()) && aExport[ nFormat ].bIsPixelFormat;
537 }
538 
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString GetExternalFilterName(sal_uInt16 nFormat, bool bExport)
OUString GetImportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define IMP_MOV
OUString GetExportFormatName(sal_uInt16 nFormat)
OUString GetImportFilterName(sal_uInt16 nFormat)
sal_uInt16 GetExportFormatNumber(const OUString &rFormatName)
OUString GetExportFormatExtension(sal_uInt16 nFormat, sal_Int32 nEntry=0)
#define IMP_JPEG
OUString GetExportInternalFilterName(sal_uInt16 nFormat)
#define EXP_JPEG
DstType sequenceToContainer(const css::uno::Sequence< SrcType > &i_Sequence)
#define EXP_SVMETAFILE
OUString GetImportFilterType(sal_uInt16 nFormat)
static bool IsFuzzing()
bool IsExportPixelFormat(sal_uInt16 nFormat)
OUString GetImportFormatShortName(sal_uInt16 nFormat)
char const sMediaType[]
OUString GetExportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
std::vector< FilterConfigCacheEntry > aExport
FilterConfigCache(bool bUseConfig)
#define IMP_SVMETAFILE
#define IMP_BMP
#define EXP_SVG
OUString GetImportFormatMediaType(sal_uInt16 nFormat)
OptionalString sType
sal_uInt16 GetImportFormatNumberForShortName(const OUString &rShortName)
sal_uInt16 GetImportFormatNumber(const OUString &rFormatName)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_uInt16 GetExportFormatNumberForShortName(const OUString &rShortName)
#define IMP_XBM
#define IMP_SVG
sal_uInt16 GetImportFormatNumberForExtension(const OUString &rExt)
get the index of the filter that matches this extension
OUString GetImportFilterTypeName(sal_uInt16 nFormat)
OUString GetImportFormatName(sal_uInt16 nFormat)
#define IMP_WMF
void CreateFilterName(const OUString &rUserDataEntry)
bool IsImportInternalFilter(sal_uInt16 nFormat)
OUString GetExportFormatMediaType(sal_uInt16 nFormat)
sal_uInt16 GetImportFormatNumberForTypeName(const OUString &rType)
sal_uInt16 GetExportFormatNumberForTypeName(const OUString &rType)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
#define EXP_WMF
sal_uInt16 GetExportFormatNumberForMediaType(const OUString &rMediaType)
#define EXP_PDF
#define IMP_PNG
#define IMP_GIF
std::vector< FilterConfigCacheEntry > aImport
Reference< XComponentContext > getProcessComponentContext()
#define IMP_PDF
#define EXP_EMF
OUString aWildcard
OUString GetExportFilterName(sal_uInt16 nFormat)
#define SVLIBRARY(Base)
#define IMP_XPM
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)
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
#define IMP_EMF
bool IsExportInternalFilter(sal_uInt16 nFormat)
static const char * InternalFilterListForSvxLight[]
sal_uInt16 nPos
OUString GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
#define GRFILTER_FORMAT_NOTFOUND
#define EXP_PNG