summaryrefslogtreecommitdiffstats
path: root/vcl/source/filter/FilterConfigCache.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/filter/FilterConfigCache.cxx')
-rw-r--r--vcl/source/filter/FilterConfigCache.cxx489
1 files changed, 489 insertions, 0 deletions
diff --git a/vcl/source/filter/FilterConfigCache.cxx b/vcl/source/filter/FilterConfigCache.cxx
new file mode 100644
index 000000000..9f3668ccc
--- /dev/null
+++ b/vcl/source/filter/FilterConfigCache.cxx
@@ -0,0 +1,489 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "FilterConfigCache.hxx"
+
+#include <o3tl/safeint.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <unotools/configmgr.hxx>
+#include <tools/svlibrary.h>
+#include <com/sun/star/uno/Any.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+using namespace ::com::sun::star::lang ; // XMultiServiceFactory
+using namespace ::com::sun::star::container ; // XNameAccess
+using namespace ::com::sun::star::uno ; // Reference
+using namespace ::com::sun::star::beans ; // PropertyValue
+using namespace ::com::sun::star::configuration ;
+
+const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameList[] =
+{
+ IMP_BMP, IMP_GIF, IMP_PNG, IMP_JPEG, IMP_TIFF, IMP_WEBP,
+ IMP_XBM, IMP_XPM, IMP_TGA, IMP_PICT, IMP_MET, IMP_RAS,
+ IMP_PCX, IMP_MOV, IMP_PSD, IMP_PCD, IMP_PBM, IMP_DXF,
+ EXP_BMP, EXP_GIF, EXP_PNG, EXP_JPEG, EXP_TIFF, EXP_WEBP,
+ nullptr
+};
+
+void FilterConfigCache::FilterConfigCacheEntry::CreateFilterName( const OUString& rUserDataEntry )
+{
+ bIsPixelFormat = false;
+ sFilterName = rUserDataEntry;
+ const char** pPtr;
+ for ( pPtr = InternalPixelFilterNameList; *pPtr; pPtr++ )
+ {
+ if ( sFilterName.equalsIgnoreAsciiCaseAscii( *pPtr ) )
+ {
+ bIsPixelFormat = true;
+ }
+ }
+}
+
+OUString FilterConfigCache::FilterConfigCacheEntry::GetShortName()
+{
+ OUString aShortName;
+ if ( !lExtensionList.empty() )
+ {
+ aShortName = lExtensionList[ 0 ];
+ if ( aShortName.startsWith( "*." ) )
+ aShortName = aShortName.replaceAt( 0, 2, u"" );
+ }
+ return aShortName;
+}
+
+/** helper to open the configuration root of the underlying
+ config package
+
+ @param sPackage
+ specify, which config package should be opened.
+ Must be one of "types" or "filters"
+
+ @return A valid object if open was successful. The access on opened
+ data will be readonly. It returns NULL in case open failed.
+
+ @throws It let pass RuntimeExceptions only.
+ */
+static Reference< XInterface > openConfig(const char* sPackage)
+{
+ Reference< XComponentContext > xContext(
+ comphelper::getProcessComponentContext() );
+ Reference< XInterface > xCfg;
+ try
+ {
+ // get access to config API (not to file!)
+ Reference< XMultiServiceFactory > xConfigProvider = theDefaultProvider::get( xContext );
+
+ PropertyValue aParam ;
+
+ // define cfg path for open
+ aParam.Name = "nodepath";
+ if (rtl_str_compareIgnoreAsciiCase(sPackage, "types") == 0)
+ aParam.Value <<= OUString( "/org.openoffice.TypeDetection.Types/Types" );
+ if (rtl_str_compareIgnoreAsciiCase(sPackage, "filters") == 0)
+ aParam.Value <<= OUString( "/org.openoffice.TypeDetection.GraphicFilter/Filters" );
+ Sequence< Any > lParams{ Any(aParam) };
+
+ // get access to file
+ xCfg = xConfigProvider->createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", lParams);
+ }
+ catch(const RuntimeException&)
+ { throw; }
+ catch(const Exception&)
+ { xCfg.clear(); }
+
+ return xCfg;
+}
+
+void FilterConfigCache::ImplInit()
+{
+ OUString const STYPE ( "Type" );
+ OUString const SUINAME ( "UIName" );
+ OUString const SFLAGS ( "Flags" );
+ OUString const SMEDIATYPE ( "MediaType" );
+ OUString const SEXTENSIONS ( "Extensions" );
+ OUString const SFORMATNAME ( "FormatName" );
+ OUString const SREALFILTERNAME ( "RealFilterName" );
+
+ // get access to config
+ Reference< XNameAccess > xTypeAccess ( openConfig("types" ), UNO_QUERY );
+ Reference< XNameAccess > xFilterAccess( openConfig("filters"), UNO_QUERY );
+
+ if ( !(xTypeAccess.is() && xFilterAccess.is()) )
+ return;
+
+ const Sequence< OUString > lAllFilter = xFilterAccess->getElementNames();
+
+ for ( const OUString& sInternalFilterName : lAllFilter )
+ {
+ Reference< XPropertySet > xFilterSet;
+ xFilterAccess->getByName( sInternalFilterName ) >>= xFilterSet;
+ if (!xFilterSet.is())
+ continue;
+
+ FilterConfigCacheEntry aEntry;
+
+ aEntry.sInternalFilterName = sInternalFilterName;
+ xFilterSet->getPropertyValue(STYPE) >>= aEntry.sType;
+ xFilterSet->getPropertyValue(SUINAME) >>= aEntry.sUIName;
+ xFilterSet->getPropertyValue(SREALFILTERNAME) >>= aEntry.sFilterType;
+ Sequence< OUString > lFlags;
+ xFilterSet->getPropertyValue(SFLAGS) >>= lFlags;
+ if (lFlags.getLength()!=1 || lFlags[0].isEmpty())
+ continue;
+ if (lFlags[0].equalsIgnoreAsciiCase("import"))
+ aEntry.nFlags = 1;
+ else if (lFlags[0].equalsIgnoreAsciiCase("export"))
+ aEntry.nFlags = 2;
+ else
+ aEntry.nFlags = 0;
+
+ OUString sFormatName;
+ xFilterSet->getPropertyValue(SFORMATNAME) >>= sFormatName;
+ aEntry.CreateFilterName( sFormatName );
+
+ Reference< XPropertySet > xTypeSet;
+ xTypeAccess->getByName( aEntry.sType ) >>= xTypeSet;
+ if (!xTypeSet.is())
+ continue;
+
+ xTypeSet->getPropertyValue(SMEDIATYPE) >>= aEntry.sMediaType;
+ css::uno::Sequence<OUString> tmp;
+ if (xTypeSet->getPropertyValue(SEXTENSIONS) >>= tmp)
+ aEntry.lExtensionList = comphelper::sequenceToContainer<std::vector<OUString>>(tmp);
+
+ // The first extension will be used
+ // to generate our internal FilterType ( BMP, WMF ... )
+ OUString aExtension( aEntry.GetShortName() );
+ if (aExtension.isEmpty())
+ continue;
+
+ if ( aEntry.nFlags & 1 )
+ aImport.push_back( aEntry );
+ if ( aEntry.nFlags & 2 )
+ aExport.push_back( aEntry );
+
+ // bFilterEntryCreated!?
+ if (!( aEntry.nFlags & 3 ))
+ continue; //? Entry was already inserted ... but following code will be suppressed?!
+ }
+};
+
+const char* FilterConfigCache::InternalFilterListForSvxLight[] =
+{
+ "bmp","1","SVBMP",
+ "bmp","2","SVBMP",
+ "dxf","1","SVDXF",
+ "eps","1","SVIEPS",
+ "eps","2","SVEEPS",
+ "gif","1","SVIGIF",
+ "gif","2","SVEGIF",
+ "jpg","1","SVIJPEG",
+ "jpg","2","SVEJPEG",
+ "mov","1","SVMOV",
+ "mov","2","SVMOV",
+ "met","1","SVMET",
+ "png","1","SVIPNG",
+ "png","2","SVEPNG",
+ "pct","1","SVPICT",
+ "pcd","1","SVPCD",
+ "psd","1","SVPSD",
+ "pcx","1","SVPCX",
+ "pbm","1","SVPBM",
+ "pgm","1","SVPBM",
+ "ppm","1","SVPBM",
+ "ras","1","SVRAS",
+ "svm","1","SVMETAFILE",
+ "svm","2","SVMETAFILE",
+ "tga","1","SVTGA",
+ "tif","1","SVTIFF",
+ "tif","2","SVTIFF",
+ "emf","1","SVEMF",
+ "emf","2","SVEMF",
+ "wmf","1","SVWMF",
+ "wmf","2","SVWMF",
+ "xbm","1","SVIXBM",
+ "xpm","1","SVIXPM",
+ "svg","1","SVISVG",
+ "svg","2","SVESVG",
+ "webp","1","SVIWEBP",
+ "webp","2","SVEWEBP",
+ nullptr
+};
+
+void FilterConfigCache::ImplInitSmart()
+{
+ const char** pPtr;
+ for ( pPtr = InternalFilterListForSvxLight; *pPtr; pPtr++ )
+ {
+ FilterConfigCacheEntry aEntry;
+
+ OUString sExtension( OUString::createFromAscii( *pPtr++ ) );
+
+ aEntry.lExtensionList.push_back(sExtension);
+
+ aEntry.sType = sExtension;
+ aEntry.sUIName = sExtension;
+
+ OString sFlags( *pPtr++ );
+ aEntry.nFlags = sFlags.toInt32();
+
+ OUString sUserData( OUString::createFromAscii( *pPtr ) );
+ aEntry.CreateFilterName( sUserData );
+
+ if ( aEntry.nFlags & 1 )
+ aImport.push_back( aEntry );
+ if ( aEntry.nFlags & 2 )
+ aExport.push_back( aEntry );
+ }
+}
+
+FilterConfigCache::FilterConfigCache(bool bConfig)
+{
+ if (bConfig)
+ bConfig = !utl::ConfigManager::IsFuzzing();
+ if (bConfig)
+ ImplInit();
+ else
+ ImplInitSmart();
+}
+
+FilterConfigCache::~FilterConfigCache()
+{
+}
+
+OUString FilterConfigCache::GetImportFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sFilterName;
+ return OUString();
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumber( std::u16string_view rFormatName )
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aImport)
+ {
+ if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+/// get the index of the filter that matches this extension
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForExtension( std::u16string_view rExt )
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aImport)
+ {
+ for ( OUString const & s : elem.lExtensionList )
+ {
+ if ( s.equalsIgnoreAsciiCase( rExt ) )
+ return nPos;
+ }
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForShortName( std::u16string_view rShortName )
+{
+ sal_uInt16 nPos = 0;
+ for (auto & elem : aImport)
+ {
+ if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+sal_uInt16 FilterConfigCache::GetImportFormatNumberForTypeName( std::u16string_view rType )
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aImport)
+ {
+ if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+OUString FilterConfigCache::GetImportFormatName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sUIName;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportFormatMediaType( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sMediaType;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportFormatShortName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].GetShortName();
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ if ( (nFormat < aImport.size()) && (o3tl::make_unsigned(nEntry) < aImport[ nFormat ].lExtensionList.size()) )
+ return aImport[ nFormat ].lExtensionList[ nEntry ];
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportFilterType( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sType;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportFilterTypeName( sal_uInt16 nFormat )
+{
+ if( nFormat < aImport.size() )
+ return aImport[ nFormat ].sFilterType;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetImportWildcard(sal_uInt16 nFormat, sal_Int32 nEntry)
+{
+ OUString aWildcard( GetImportFormatExtension( nFormat, nEntry ) );
+ if ( !aWildcard.isEmpty() )
+ aWildcard = aWildcard.replaceAt( 0, 0, u"*." );
+ return aWildcard;
+}
+
+OUString FilterConfigCache::GetExportFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sFilterName;
+ return OUString();
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumber(std::u16string_view rFormatName)
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aExport)
+ {
+ if ( elem.sUIName.equalsIgnoreAsciiCase( rFormatName ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForMediaType( std::u16string_view rMediaType )
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aExport)
+ {
+ if ( elem.sMediaType.equalsIgnoreAsciiCase( rMediaType ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForShortName( std::u16string_view rShortName )
+{
+ sal_uInt16 nPos = 0;
+ for (auto & elem : aExport)
+ {
+ if ( elem.GetShortName().equalsIgnoreAsciiCase( rShortName ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+sal_uInt16 FilterConfigCache::GetExportFormatNumberForTypeName( std::u16string_view rType )
+{
+ sal_uInt16 nPos = 0;
+ for (auto const& elem : aExport)
+ {
+ if ( elem.sType.equalsIgnoreAsciiCase( rType ) )
+ return nPos;
+ ++nPos;
+ }
+ return GRFILTER_FORMAT_NOTFOUND;
+}
+
+OUString FilterConfigCache::GetExportFormatName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sUIName;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetExportFormatMediaType( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sMediaType;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetExportFormatShortName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].GetShortName();
+ return OUString();
+}
+
+OUString FilterConfigCache::GetExportFormatExtension( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ if ( (nFormat < aExport.size()) && (o3tl::make_unsigned(nEntry) < aExport[ nFormat ].lExtensionList.size()) )
+ return aExport[ nFormat ].lExtensionList[ nEntry ];
+ return OUString();
+}
+
+OUString FilterConfigCache::GetExportInternalFilterName( sal_uInt16 nFormat )
+{
+ if( nFormat < aExport.size() )
+ return aExport[ nFormat ].sInternalFilterName;
+ return OUString();
+}
+
+OUString FilterConfigCache::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
+{
+ OUString aWildcard( GetExportFormatExtension( nFormat, nEntry ) );
+ if ( !aWildcard.isEmpty() )
+ aWildcard = aWildcard.replaceAt( 0, 0, u"*." );
+ return aWildcard;
+}
+
+bool FilterConfigCache::IsExportPixelFormat( sal_uInt16 nFormat )
+{
+ return (nFormat < aExport.size()) && aExport[ nFormat ].bIsPixelFormat;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */