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