20 #include <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/configuration/theDefaultProvider.hpp>
22 #include <com/sun/star/container/XContainerQuery.hpp>
23 #include <com/sun/star/container/XNameAccess.hpp>
24 #include <com/sun/star/embed/VerbDescriptor.hpp>
25 #include <com/sun/star/document/XTypeDetection.hpp>
27 #include <osl/diagnose.h>
35 #include <rtl/ustrbuf.hxx>
46 throw uno::RuntimeException();
52 OUStringBuffer aResult;
54 if ( aClassID.getLength() == 16 )
56 for ( sal_Int32 nInd = 0; nInd < aClassID.getLength(); nInd++ )
58 if ( nInd == 4 || nInd == 6 || nInd == 8 || nInd == 10 )
61 sal_Int32 nDigit1 =
static_cast<sal_Int32
>(
static_cast<sal_uInt8>(aClassID[nInd]) / 16 );
62 sal_Int32 nDigit2 =
static_cast<sal_uInt8>(aClassID[nInd]) % 16;
63 aResult.append( OUString::number(nDigit1, 16) + OUString::number( nDigit2, 16 ) );
67 return aResult.makeStringAndClear();
73 if ( aChar >=
'0' && aChar <=
'9' )
75 else if ( aChar >=
'a' && aChar <=
'f' )
76 return aChar -
'a' + 10;
77 else if ( aChar >=
'A' && aChar <=
'F' )
78 return aChar -
'A' + 10;
86 size_t nLength = aClassID.size();
90 uno::Sequence< sal_Int8 > aResult( 16 );
91 auto pResult = aResult.getArray();
93 size_t nStrPointer = 0;
94 sal_Int32 nSeqInd = 0;
95 while( nSeqInd < 16 && nStrPointer + 1
U < nLength )
100 if ( nDigit1 > 15 || nDigit2 > 15 )
103 pResult[nSeqInd++] =
static_cast<sal_Int8>( nDigit1 * 16 + nDigit2 );
105 if ( nStrPointer < nLength && aCharClassID[nStrPointer] ==
'-' )
109 if ( nSeqInd == 16 && nStrPointer == nLength )
113 return uno::Sequence< sal_Int8 >();
119 uno::Reference< container::XNameAccess > xConfig;
131 "com.sun.star.configuration.ConfigurationAccess",
135 catch( uno::Exception& )
144 std::unique_lock aGuard(
m_aMutex );
148 "/org.openoffice.Office.Embedding/Objects" );
156 std::unique_lock aGuard(
m_aMutex );
160 "/org.openoffice.Office.Embedding/Verbs");
168 std::unique_lock aGuard(
m_aMutex );
172 "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations");
180 std::unique_lock aGuard(
m_aMutex );
184 m_xContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.FilterFactory",
m_xContext),
193 OUString aDocServiceName;
197 uno::Reference< container::XNameAccess > xFilterFactory(
199 uno::UNO_SET_THROW );
201 uno::Any aFilterAnyData = xFilterFactory->getByName( aFilterName );
202 uno::Sequence< beans::PropertyValue > aFilterData;
203 if ( aFilterAnyData >>= aFilterData )
205 for (
const auto & prop : std::as_const(aFilterData) )
206 if ( prop.Name ==
"DocumentService" )
207 prop.
Value >>= aDocServiceName;
210 catch( uno::Exception& )
213 return aDocServiceName;
219 uno::Reference< container::XContainerQuery > xTypeCFG(
220 m_xContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.TypeDetection",
m_xContext),
228 uno::Sequence < beans::NamedValue >
aSeq { {
"MediaType", css::uno::Any(aMediaType) } };
230 uno::Reference < container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties(
aSeq );
231 while ( xEnum->hasMoreElements() )
233 uno::Sequence< beans::PropertyValue > aType;
234 if ( xEnum->nextElement() >>= aType )
236 for (
const auto & prop : std::as_const(aType) )
238 OUString aFilterName;
239 if ( prop.Name ==
"PreferredFilter"
240 && ( prop.Value >>= aFilterName ) && !aFilterName.isEmpty() )
243 if ( !aDocumentName.isEmpty() )
244 return aDocumentName;
250 catch( uno::Exception& )
259 embed::VerbDescriptor& aDescriptor )
261 bool bResult =
false;
264 uno::Reference< container::XNameAccess > xVerbsProps;
267 if ( xVerbsConfig.is() && ( xVerbsConfig->getByName( aVerbShortcut ) >>= xVerbsProps ) && xVerbsProps.is() )
269 embed::VerbDescriptor aTempDescr;
270 static constexpr OUStringLiteral sVerbID =
u"VerbID";
271 static constexpr OUStringLiteral sVerbUIName =
u"VerbUIName";
272 static constexpr OUStringLiteral sVerbFlags =
u"VerbFlags";
273 static constexpr OUStringLiteral sVerbAttributes =
u"VerbAttributes";
274 if ( ( xVerbsProps->getByName(sVerbID) >>= aTempDescr.VerbID )
275 && ( xVerbsProps->getByName(sVerbUIName) >>= aTempDescr.VerbName )
276 && ( xVerbsProps->getByName(sVerbFlags) >>= aTempDescr.VerbFlags )
277 && ( xVerbsProps->getByName(sVerbAttributes) >>= aTempDescr.VerbAttributes ) )
279 aDescriptor = aTempDescr;
284 catch( uno::Exception& )
293 const uno::Sequence< sal_Int8 >& aClassID,
294 const uno::Reference< container::XNameAccess >& xObjectProps )
296 uno::Sequence< beans::NamedValue > aResult;
298 if ( aClassID.getLength() == 16 )
302 const uno::Sequence< OUString > aObjPropNames = xObjectProps->getElementNames();
304 aResult.realloc( aObjPropNames.getLength() + 1 );
305 auto pResult = aResult.getArray();
306 pResult[0].Name =
"ClassID";
307 pResult[0].Value <<= aClassID;
309 for ( sal_Int32 nInd = 0; nInd < aObjPropNames.getLength(); nInd++ )
311 pResult[nInd + 1].Name = aObjPropNames[nInd];
313 if ( aObjPropNames[nInd] ==
"ObjectVerbs" )
315 uno::Sequence< OUString > aVerbShortcuts;
316 if ( !(xObjectProps->getByName( aObjPropNames[nInd] ) >>= aVerbShortcuts) )
317 throw uno::RuntimeException();
318 uno::Sequence< embed::VerbDescriptor > aVerbDescriptors( aVerbShortcuts.getLength() );
319 auto aVerbDescriptorsRange = asNonConstRange(aVerbDescriptors);
320 for ( sal_Int32 nVerbI = 0; nVerbI < aVerbShortcuts.getLength(); nVerbI++ )
321 if ( !
GetVerbByShortcut( aVerbShortcuts[nVerbI], aVerbDescriptorsRange[nVerbI] ) )
322 throw uno::RuntimeException();
324 pResult[nInd+1].Value <<= aVerbDescriptors;
327 pResult[nInd+1].Value = xObjectProps->getByName( aObjPropNames[nInd] );
330 catch( uno::Exception& )
332 aResult.realloc( 0 );
342 OUString aStringClassID;
347 if ( xMediaTypeConfig.is() )
348 xMediaTypeConfig->getByName( aMediaType ) >>= aStringClassID;
350 catch( uno::Exception& )
354 return aStringClassID;
360 const OUString& aStringClassID )
362 uno::Sequence< beans::NamedValue > aObjProps;
367 aObjProps = { {
"ObjectFactory",
368 uno::Any(OUString(
"com.sun.star.embed.OOoSpecialEmbeddedObjectFactory")) },
369 {
"ClassID",
uno::Any(aClassID) } };
373 if ( aClassID.getLength() == 16 )
376 uno::Reference< container::XNameAccess > xObjectProps;
380 if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
383 catch( uno::Exception& )
393 const uno::Sequence< sal_Int8 >& aClassID )
395 uno::Sequence< beans::NamedValue > aObjProps;
398 aObjProps = { {
"ObjectFactory",
399 uno::Any(OUString(
"com.sun.star.embed.OOoSpecialEmbeddedObjectFactory")) },
400 {
"ClassID",
uno::Any(aClassID) } };
404 if ( !aStringClassID.isEmpty() )
407 uno::Reference< container::XNameAccess > xObjectProps;
410 if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
413 catch( uno::Exception& )
424 uno::Sequence< beans::NamedValue > aObject =
426 if ( aObject.hasElements() )
430 if ( !aDocumentName.isEmpty() )
433 return uno::Sequence< beans::NamedValue >();
440 if ( !aDocumentName.isEmpty() )
443 return uno::Sequence< beans::NamedValue >();
449 if ( !aDocName.empty() )
452 if ( xObjConfig.is() )
456 const uno::Sequence< OUString > aClassIDs = xObjConfig->getElementNames();
457 for (
const OUString &
id : aClassIDs )
459 uno::Reference< container::XNameAccess > xObjectProps;
460 OUString aEntryDocName;
462 if ( ( xObjConfig->getByName(
id ) >>= xObjectProps ) && xObjectProps.is()
463 && ( xObjectProps->getByName(
"ObjectDocumentServiceName") >>= aEntryDocName )
464 && aEntryDocName == aDocName )
471 catch( uno::Exception& )
476 return uno::Sequence< beans::NamedValue >();
490 if ( !aStringClassID.isEmpty() )
493 uno::Reference< container::XNameAccess > xObjectProps;
496 if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
497 xObjectProps->getByName(
"ObjectFactory") >>= aResult;
499 catch( uno::Exception& )
503 return "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory";
515 if ( !aDocName.empty() )
518 if ( xObjConfig.is() )
522 const uno::Sequence< OUString > aClassIDs = xObjConfig->getElementNames();
523 for (
const OUString &
id : aClassIDs )
525 uno::Reference< container::XNameAccess > xObjectProps;
526 OUString aEntryDocName;
528 if ( ( xObjConfig->getByName(
id ) >>= xObjectProps ) && xObjectProps.is()
529 && ( xObjectProps->getByName(
"ObjectDocumentServiceName" ) >>= aEntryDocName )
530 && aEntryDocName == aDocName )
532 xObjectProps->getByName(
"ObjectFactory") >>= aResult;
537 catch( uno::Exception& )
550 if ( aResult.isEmpty() )
553 if ( !aDocumentName.isEmpty() )
562 uno::Sequence< beans::PropertyValue >& aMediaDescr,
565 OUString aFilterName;
567 for (
const auto & prop : std::as_const(aMediaDescr) )
568 if ( prop.Name ==
"FilterName" )
569 prop.Value >>= aFilterName;
571 if ( aFilterName.isEmpty() )
575 uno::Reference< document::XTypeDetection > xTypeDetection(
576 m_xContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.TypeDetection",
m_xContext),
577 uno::UNO_QUERY_THROW );
580 uno::Sequence< beans::PropertyValue > aTempMD( aMediaDescr );
583 OUString aTypeName = xTypeDetection->queryTypeByDescriptor( aTempMD,
true );
586 for (
const auto & prop : std::as_const(aTempMD) )
587 if ( prop.Name ==
"FilterName" )
588 prop.Value >>= aFilterName;
590 if ( !aFilterName.isEmpty() )
592 sal_Int32 nOldLen = aMediaDescr.getLength();
593 aMediaDescr.realloc( nOldLen + 1 );
594 auto pMediaDescr = aMediaDescr.getArray();
595 pMediaDescr[nOldLen].Name =
"FilterName";
596 pMediaDescr[ nOldLen ].Value <<= aFilterName;
599 else if ( !aTypeName.isEmpty() && !bIgnoreType )
601 uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY );
602 uno::Sequence< beans::PropertyValue >
aTypes;
604 if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
606 for (
const auto & prop : std::as_const(aTypes) )
608 if ( prop.Name ==
"PreferredFilter" && ( prop.Value >>= aFilterName ) )
610 sal_Int32 nOldLen = aMediaDescr.getLength();
611 aMediaDescr.realloc( nOldLen + 1 );
612 auto pMediaDescr = aMediaDescr.getArray();
613 pMediaDescr[nOldLen].Name =
"FilterName";
614 pMediaDescr[ nOldLen ].Value = prop.Value;
626 uno::Sequence< beans::PropertyValue >& aMediaDescr,
627 uno::Sequence< beans::NamedValue >& aObject )
630 for (
const auto & nv : std::as_const(aObject) )
631 if ( nv.Name ==
"ObjectDocumentServiceName" )
633 nv.Value >>= aDocName;
637 OSL_ENSURE( !aDocName.isEmpty(),
"The name must exist at this point!" );
640 bool bNeedsAddition =
true;
641 for ( sal_Int32 nMedInd = 0; nMedInd < aMediaDescr.getLength(); nMedInd++ )
642 if ( aMediaDescr[nMedInd].Name ==
"DocumentService" )
644 aMediaDescr.getArray()[nMedInd].Value <<= aDocName;
645 bNeedsAddition =
false;
649 if ( bNeedsAddition )
651 sal_Int32 nOldLen = aMediaDescr.getLength();
652 aMediaDescr.realloc( nOldLen + 1 );
653 auto pMediaDescr = aMediaDescr.getArray();
654 pMediaDescr[nOldLen].Name =
"DocumentService";
655 pMediaDescr[nOldLen].Value <<= aDocName;
663 SfxFilterFlags MimeConfigurationHelper::GetFilterFlags(
const OUString& aFilterName )
668 if ( !aFilterName.isEmpty() )
670 uno::Reference< container::XNameAccess > xFilterFactory(
672 uno::UNO_SET_THROW );
674 uno::Any aFilterAny = xFilterFactory->getByName( aFilterName );
675 uno::Sequence< beans::PropertyValue >
aData;
676 if ( aFilterAny >>= aData )
679 nFlags =
static_cast<SfxFilterFlags>(aFilterHM.getUnpackedValueOrDefault(
"Flags", sal_Int32(0) ));
682 }
catch( uno::Exception& )
688 bool MimeConfigurationHelper::AddFilterNameCheckOwnFile(
689 uno::Sequence< beans::PropertyValue >& aMediaDescr )
692 if ( !aFilterName.isEmpty() )
708 if ( !aServiceName.isEmpty() &&
nVersion )
711 uno::Reference< container::XContainerQuery > xFilterQuery(
713 uno::UNO_QUERY_THROW );
715 uno::Sequence< beans::NamedValue > aSearchRequest
717 {
"DocumentService", css::uno::Any(aServiceName) },
718 {
"FileFormatVersion", css::uno::Any(nVersion) }
721 uno::Reference< container::XEnumeration > xFilterEnum =
722 xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest );
725 if ( xFilterEnum.is() )
726 while ( xFilterEnum->hasMoreElements() )
728 uno::Sequence< beans::PropertyValue > aProps;
729 if ( xFilterEnum->nextElement() >>= aProps )
733 for (
const auto & rPropVal : aProps)
735 if (rPropVal.Name ==
"Flags")
738 if (rPropVal.Value >>= nTmp)
741 else if (rPropVal.Name ==
"Name")
742 rPropVal.Value >>= sName;
764 catch( uno::Exception& )
773 OUString aExportFilterName;
777 if ( !aImportFilterName.isEmpty() )
779 uno::Reference< container::XNameAccess > xFilterFactory(
781 uno::UNO_SET_THROW );
783 uno::Any aImpFilterAny = xFilterFactory->getByName( aImportFilterName );
784 uno::Sequence< beans::PropertyValue > aImpData;
785 if ( aImpFilterAny >>= aImpData )
792 OSL_FAIL(
"This is no import filter!" );
793 throw uno::Exception(
"this is no import filter",
nullptr);
798 aExportFilterName = aImportFilterName;
805 OSL_ENSURE( !aDocumentServiceName.isEmpty() && !aTypeName.isEmpty(),
"Incomplete filter data!" );
806 if ( !(aDocumentServiceName.isEmpty() || aTypeName.isEmpty()) )
808 uno::Sequence< beans::NamedValue > aSearchRequest
810 {
"Type", css::uno::Any(aTypeName) },
811 {
"DocumentService", css::uno::Any(aDocumentServiceName) }
814 uno::Sequence< beans::PropertyValue > aExportFilterProps =
SearchForFilter(
815 uno::Reference< container::XContainerQuery >( xFilterFactory, uno::UNO_QUERY_THROW ),
817 SfxFilterFlags::EXPORT,
820 if ( aExportFilterProps.hasElements() )
830 catch( uno::Exception& )
833 return aExportFilterName;
839 const uno::Reference< container::XContainerQuery >& xFilterQuery,
840 const uno::Sequence< beans::NamedValue >& aSearchRequest,
844 uno::Sequence< beans::PropertyValue > aFilterProps;
845 uno::Reference< container::XEnumeration > xFilterEnum =
846 xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest );
850 if ( xFilterEnum.is() )
852 while ( xFilterEnum->hasMoreElements() )
854 uno::Sequence< beans::PropertyValue > aProps;
855 if ( xFilterEnum->nextElement() >>= aProps )
860 if ( ( ( nFlags & nMustFlags ) == nMustFlags ) && !( nFlags & nDontFlags ) )
864 aFilterProps = aProps;
867 else if ( !aFilterProps.hasElements() )
868 aFilterProps = aProps;
880 return aClassID1 == aClassID2;
888 uno::Sequence< sal_Int8 > aResult{
static_cast<sal_Int8>( n1 >> 24 ),
889 static_cast<sal_Int8>( ( n1 << 8 ) >> 24 ),
890 static_cast<sal_Int8>( ( n1 << 16 ) >> 24 ),
891 static_cast<sal_Int8>( ( n1 << 24 ) >> 24 ),
892 static_cast<sal_Int8>( n2 >> 8 ),
893 static_cast<sal_Int8>( ( n2 << 8 ) >> 8 ),
894 static_cast<sal_Int8>( n3 >> 8 ),
895 static_cast<sal_Int8>( ( n3 << 8 ) >> 8 ),
896 static_cast<sal_Int8>( b8 ),
898 static_cast<sal_Int8>( b10 ),
900 static_cast<sal_Int8>( b12 ),
902 static_cast<sal_Int8>( b14 ),
css::uno::Reference< css::container::XNameAccess > GetVerbsConfiguration()
const char *const aClassID
OUString GetDefaultFilterFromServiceName(const OUString &aServName, sal_Int32 nVersion)
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByFilter(const OUString &aFilterName)
bool GetVerbByShortcut(const OUString &aVerbShortcut, css::embed::VerbDescriptor &aDescriptor)
OUString UpdateMediaDescriptorWithFilterName(css::uno::Sequence< css::beans::PropertyValue > &aMediaDescr, bool bIgnoreType)
OUString GetFactoryNameByDocumentName(std::u16string_view aDocName)
OUString GetExportFilterFromImportFilter(const OUString &aImportFilterName)
css::uno::Reference< css::container::XNameAccess > GetFilterFactory()
MimeConfigurationHelper(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
OUString GetFactoryNameByStringClassID(const OUString &aStringClassID)
OUString GetDocServiceNameFromMediaType(const OUString &aMediaType)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
css::uno::Reference< css::container::XNameAccess > GetMediaTypeConfiguration()
constexpr OUStringLiteral aData
css::uno::Reference< css::container::XNameAccess > m_xVerbsConfig
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
check if the specified item exists and return its (unpacked!) value or it returns the specified defau...
OUString GetFactoryNameByMediaType(const OUString &aMediaType)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Init list for property sequences that wrap the PropertyValues in Anys.
static css::uno::Sequence< sal_Int8 > GetSequenceClassIDRepresentation(std::u16string_view aClassID)
#define SO3_DUMMY_CLASSID
OUString GetFactoryNameByClassID(const css::uno::Sequence< sal_Int8 > &aClassID)
css::uno::Reference< css::container::XNameAccess > GetConfigurationByPathImpl(const OUString &aPath)
OUString GetExplicitlyRegisteredObjClassID(const OUString &aMediaType)
OUString GetDocServiceNameFromFilter(const OUString &aFilterName)
static sal_uInt8 GetDigit_Impl(char aChar)
static bool ClassIDsEqual(const css::uno::Sequence< sal_Int8 > &aClassID1, const css::uno::Sequence< sal_Int8 > &aClassID2)
static OUString GetStringClassIDRepresentation(const css::uno::Sequence< sal_Int8 > &aClassID)
static css::uno::Sequence< css::beans::PropertyValue > SearchForFilter(const css::uno::Reference< css::container::XContainerQuery > &xFilterQuery, const css::uno::Sequence< css::beans::NamedValue > &aSearchRequest, SfxFilterFlags nMustFlags, SfxFilterFlags nDontFlags)
static css::uno::Sequence< sal_Int8 > GetSequenceClassID(sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3, sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11, sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15)
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByStringClassID(const OUString &aStringClassID)
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByClassID(const css::uno::Sequence< sal_Int8 > &aClassID)
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByDocumentName(std::u16string_view aDocumentName)
css::uno::Reference< css::container::XNameAccess > GetObjConfiguration()
Sequence< sal_Int8 > aSeq
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByMediaType(const OUString &aMediaType)
css::uno::Sequence< css::beans::NamedValue > GetObjPropsFromConfigEntry(const css::uno::Sequence< sal_Int8 > &aClassID, const css::uno::Reference< css::container::XNameAccess > &xObjectProps)
css::uno::Reference< css::container::XNameAccess > m_xFilterFactory
css::uno::Reference< css::container::XNameAccess > m_xObjectConfig
css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvider
Reference< XComponentContext > m_xContext
css::uno::Reference< css::container::XNameAccess > m_xMediaTypeConfig