1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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/document/XTypeDetection.hpp>
25 #include <osl/diagnose.h>
27 #include <comphelper/fileformat.h>
28 #include <comphelper/mimeconfighelper.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <comphelper/classids.hxx>
31 #include <comphelper/sequenceashashmap.hxx>
32 #include <comphelper/documentconstants.hxx>
35 using namespace ::com::sun::star
;
36 using namespace comphelper
;
39 MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference
< uno::XComponentContext
>& rxContext
)
40 : m_xContext( rxContext
)
42 if ( !m_xContext
.is() )
43 throw uno::RuntimeException();
47 OUString
MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence
< sal_Int8
>& aClassID
)
51 if ( aClassID
.getLength() == 16 )
53 for ( sal_Int32 nInd
= 0; nInd
< aClassID
.getLength(); nInd
++ )
55 if ( nInd
== 4 || nInd
== 6 || nInd
== 8 || nInd
== 10 )
58 sal_Int32 nDigit1
= (sal_Int32
)( (sal_uInt8
)aClassID
[nInd
] / 16 );
59 sal_Int32 nDigit2
= (sal_uInt8
)aClassID
[nInd
] % 16;
60 aResult
+= OUString::number( nDigit1
, 16 );
61 aResult
+= OUString::number( nDigit2
, 16 );
69 sal_uInt8
GetDigit_Impl( sal_Char aChar
)
71 if ( aChar
>= '0' && aChar
<= '9' )
73 else if ( aChar
>= 'a' && aChar
<= 'f' )
74 return aChar
- 'a' + 10;
75 else if ( aChar
>= 'A' && aChar
<= 'F' )
76 return aChar
- 'A' + 10;
82 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassIDRepresentation( const OUString
& aClassID
)
84 sal_Int32 nLength
= aClassID
.getLength();
87 OString aCharClassID
= OUStringToOString( aClassID
, RTL_TEXTENCODING_ASCII_US
);
88 const sal_Char
* pString
= aCharClassID
.getStr();
91 uno::Sequence
< sal_Int8
> aResult( 16 );
93 sal_Int32 nStrPointer
= 0;
94 sal_Int32 nSeqInd
= 0;
95 while( nSeqInd
< 16 && nStrPointer
+ 1 < nLength
)
97 sal_uInt8 nDigit1
= GetDigit_Impl( pString
[nStrPointer
++] );
98 sal_uInt8 nDigit2
= GetDigit_Impl( pString
[nStrPointer
++] );
100 if ( nDigit1
> 15 || nDigit2
> 15 )
103 aResult
[nSeqInd
++] = (sal_Int8
)( nDigit1
* 16 + nDigit2
);
105 if ( nStrPointer
< nLength
&& pString
[nStrPointer
] == '-' )
109 if ( nSeqInd
== 16 && nStrPointer
== nLength
)
114 return uno::Sequence
< sal_Int8
>();
118 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetConfigurationByPath( const OUString
& aPath
)
120 osl::MutexGuard
aGuard( m_aMutex
);
122 uno::Reference
< container::XNameAccess
> xConfig
;
126 if ( !m_xConfigProvider
.is() )
127 m_xConfigProvider
= configuration::theDefaultProvider::get( m_xContext
);
129 uno::Sequence
< uno::Any
> aArgs( 1 );
130 beans::PropertyValue aPathProp
;
131 aPathProp
.Name
= "nodepath";
132 aPathProp
.Value
<<= aPath
;
133 aArgs
[0] <<= aPathProp
;
135 xConfig
= uno::Reference
< container::XNameAccess
>(
136 m_xConfigProvider
->createInstanceWithArguments(
137 OUString( "com.sun.star.configuration.ConfigurationAccess" ),
141 catch( uno::Exception
& )
148 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetObjConfiguration()
150 osl::MutexGuard
aGuard( m_aMutex
);
152 if ( !m_xObjectConfig
.is() )
153 m_xObjectConfig
= GetConfigurationByPath(
154 OUString( "/org.openoffice.Office.Embedding/Objects" ) );
156 return m_xObjectConfig
;
160 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetVerbsConfiguration()
162 osl::MutexGuard
aGuard( m_aMutex
);
164 if ( !m_xVerbsConfig
.is() )
165 m_xVerbsConfig
= GetConfigurationByPath(
166 OUString( "/org.openoffice.Office.Embedding/Verbs" ));
168 return m_xVerbsConfig
;
172 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetMediaTypeConfiguration()
174 osl::MutexGuard
aGuard( m_aMutex
);
176 if ( !m_xMediaTypeConfig
.is() )
177 m_xMediaTypeConfig
= GetConfigurationByPath(
178 OUString( "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations" ));
180 return m_xMediaTypeConfig
;
184 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetFilterFactory()
186 osl::MutexGuard
aGuard( m_aMutex
);
188 if ( !m_xFilterFactory
.is() )
189 m_xFilterFactory
.set(
190 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", m_xContext
),
193 return m_xFilterFactory
;
197 OUString
MimeConfigurationHelper::GetDocServiceNameFromFilter( const OUString
& aFilterName
)
199 OUString aDocServiceName
;
203 uno::Reference
< container::XNameAccess
> xFilterFactory(
205 uno::UNO_SET_THROW
);
207 uno::Any aFilterAnyData
= xFilterFactory
->getByName( aFilterName
);
208 uno::Sequence
< beans::PropertyValue
> aFilterData
;
209 if ( aFilterAnyData
>>= aFilterData
)
211 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
212 if ( aFilterData
[nInd
].Name
== "DocumentService" )
213 aFilterData
[nInd
].Value
>>= aDocServiceName
;
216 catch( uno::Exception
& )
219 return aDocServiceName
;
223 OUString
MimeConfigurationHelper::GetDocServiceNameFromMediaType( const OUString
& aMediaType
)
225 uno::Reference
< container::XContainerQuery
> xTypeCFG(
226 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext
),
233 // make query for all types matching the properties
234 uno::Sequence
< beans::NamedValue
> aSeq( 1 );
235 aSeq
[0].Name
= "MediaType";
236 aSeq
[0].Value
<<= aMediaType
;
238 uno::Reference
< container::XEnumeration
> xEnum
= xTypeCFG
->createSubSetEnumerationByProperties( aSeq
);
239 while ( xEnum
->hasMoreElements() )
241 uno::Sequence
< beans::PropertyValue
> aType
;
242 if ( xEnum
->nextElement() >>= aType
)
244 for ( sal_Int32 nInd
= 0; nInd
< aType
.getLength(); nInd
++ )
246 OUString aFilterName
;
247 if ( aType
[nInd
].Name
== "PreferredFilter"
248 && ( aType
[nInd
].Value
>>= aFilterName
) && !aFilterName
.isEmpty() )
250 OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
251 if ( !aDocumentName
.isEmpty() )
252 return aDocumentName
;
258 catch( uno::Exception
& )
266 bool MimeConfigurationHelper::GetVerbByShortcut( const OUString
& aVerbShortcut
,
267 embed::VerbDescriptor
& aDescriptor
)
269 bool bResult
= false;
271 uno::Reference
< container::XNameAccess
> xVerbsConfig
= GetVerbsConfiguration();
272 uno::Reference
< container::XNameAccess
> xVerbsProps
;
275 if ( xVerbsConfig
.is() && ( xVerbsConfig
->getByName( aVerbShortcut
) >>= xVerbsProps
) && xVerbsProps
.is() )
277 embed::VerbDescriptor aTempDescr
;
278 if ( ( xVerbsProps
->getByName("VerbID") >>= aTempDescr
.VerbID
)
279 && ( xVerbsProps
->getByName("VerbUIName") >>= aTempDescr
.VerbName
)
280 && ( xVerbsProps
->getByName("VerbFlags") >>= aTempDescr
.VerbFlags
)
281 && ( xVerbsProps
->getByName("VerbAttributes") >>= aTempDescr
.VerbAttributes
) )
283 aDescriptor
= aTempDescr
;
288 catch( uno::Exception
& )
296 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjPropsFromConfigEntry(
297 const uno::Sequence
< sal_Int8
>& aClassID
,
298 const uno::Reference
< container::XNameAccess
>& xObjectProps
)
300 uno::Sequence
< beans::NamedValue
> aResult
;
302 if ( aClassID
.getLength() == 16 )
306 uno::Sequence
< OUString
> aObjPropNames
= xObjectProps
->getElementNames();
308 aResult
.realloc( aObjPropNames
.getLength() + 1 );
309 aResult
[0].Name
= "ClassID";
310 aResult
[0].Value
<<= aClassID
;
312 for ( sal_Int32 nInd
= 0; nInd
< aObjPropNames
.getLength(); nInd
++ )
314 aResult
[nInd
+ 1].Name
= aObjPropNames
[nInd
];
316 if ( aObjPropNames
[nInd
] == "ObjectVerbs" )
318 uno::Sequence
< OUString
> aVerbShortcuts
;
319 if ( xObjectProps
->getByName( aObjPropNames
[nInd
] ) >>= aVerbShortcuts
)
321 uno::Sequence
< embed::VerbDescriptor
> aVerbDescriptors( aVerbShortcuts
.getLength() );
322 for ( sal_Int32 nVerbI
= 0; nVerbI
< aVerbShortcuts
.getLength(); nVerbI
++ )
323 if ( !GetVerbByShortcut( aVerbShortcuts
[nVerbI
], aVerbDescriptors
[nVerbI
] ) )
324 throw uno::RuntimeException();
326 aResult
[nInd
+1].Value
<<= aVerbDescriptors
;
329 throw uno::RuntimeException();
332 aResult
[nInd
+1].Value
= xObjectProps
->getByName( aObjPropNames
[nInd
] );
335 catch( uno::Exception
& )
337 aResult
.realloc( 0 );
345 OUString
MimeConfigurationHelper::GetExplicitlyRegisteredObjClassID( const OUString
& aMediaType
)
347 OUString aStringClassID
;
349 uno::Reference
< container::XNameAccess
> xMediaTypeConfig
= GetMediaTypeConfiguration();
352 if ( xMediaTypeConfig
.is() )
353 xMediaTypeConfig
->getByName( aMediaType
) >>= aStringClassID
;
355 catch( uno::Exception
& )
359 return aStringClassID
;
364 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByStringClassID(
365 const OUString
& aStringClassID
)
367 uno::Sequence
< beans::NamedValue
> aObjProps
;
369 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
370 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
372 aObjProps
.realloc(2);
373 aObjProps
[0].Name
= "ObjectFactory";
374 aObjProps
[0].Value
<<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
375 aObjProps
[1].Name
= "ClassID";
376 aObjProps
[1].Value
<<= aClassID
;
380 if ( aClassID
.getLength() == 16 )
382 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
383 uno::Reference
< container::XNameAccess
> xObjectProps
;
386 // TODO/LATER: allow to provide ClassID string in any format, only digits are counted
387 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
388 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
390 catch( uno::Exception
& )
399 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByClassID(
400 const uno::Sequence
< sal_Int8
>& aClassID
)
402 uno::Sequence
< beans::NamedValue
> aObjProps
;
403 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
405 aObjProps
.realloc(2);
406 aObjProps
[0].Name
= "ObjectFactory";
407 aObjProps
[0].Value
<<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
408 aObjProps
[1].Name
= "ClassID";
409 aObjProps
[1].Value
<<= aClassID
;
412 OUString aStringClassID
= GetStringClassIDRepresentation( aClassID
);
413 if ( !aStringClassID
.isEmpty() )
415 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
416 uno::Reference
< container::XNameAccess
> xObjectProps
;
419 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
420 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
422 catch( uno::Exception
& )
431 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByMediaType( const OUString
& aMediaType
)
433 uno::Sequence
< beans::NamedValue
> aObject
=
434 GetObjectPropsByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
435 if ( aObject
.getLength() )
438 OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
439 if ( !aDocumentName
.isEmpty() )
440 return GetObjectPropsByDocumentName( aDocumentName
);
442 return uno::Sequence
< beans::NamedValue
>();
446 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByFilter( const OUString
& aFilterName
)
448 OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
449 if ( !aDocumentName
.isEmpty() )
450 return GetObjectPropsByDocumentName( aDocumentName
);
452 return uno::Sequence
< beans::NamedValue
>();
456 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByDocumentName( const OUString
& aDocName
)
458 if ( !aDocName
.isEmpty() )
460 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
461 if ( xObjConfig
.is() )
465 uno::Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
466 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
468 uno::Reference
< container::XNameAccess
> xObjectProps
;
469 OUString aEntryDocName
;
471 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
472 && ( xObjectProps
->getByName("ObjectDocumentServiceName") >>= aEntryDocName
)
473 && aEntryDocName
== aDocName
)
475 return GetObjPropsFromConfigEntry( GetSequenceClassIDRepresentation( aClassIDs
[nInd
] ),
480 catch( uno::Exception
& )
485 return uno::Sequence
< beans::NamedValue
>();
489 OUString
MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence
< sal_Int8
>& aClassID
)
491 return GetFactoryNameByStringClassID( GetStringClassIDRepresentation( aClassID
) );
495 OUString
MimeConfigurationHelper::GetFactoryNameByStringClassID( const OUString
& aStringClassID
)
499 if ( !aStringClassID
.isEmpty() )
501 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
502 uno::Reference
< container::XNameAccess
> xObjectProps
;
505 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
506 xObjectProps
->getByName("ObjectFactory") >>= aResult
;
508 catch( uno::Exception
& )
510 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
511 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
512 return OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
520 OUString
MimeConfigurationHelper::GetFactoryNameByDocumentName( const OUString
& aDocName
)
524 if ( !aDocName
.isEmpty() )
526 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
527 if ( xObjConfig
.is() )
531 uno::Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
532 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
534 uno::Reference
< container::XNameAccess
> xObjectProps
;
535 OUString aEntryDocName
;
537 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
538 && ( xObjectProps
->getByName(
539 OUString( "ObjectDocumentServiceName" ) ) >>= aEntryDocName
)
540 && aEntryDocName
== aDocName
)
542 xObjectProps
->getByName("ObjectFactory") >>= aResult
;
547 catch( uno::Exception
& )
557 OUString
MimeConfigurationHelper::GetFactoryNameByMediaType( const OUString
& aMediaType
)
559 OUString aResult
= GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
561 if ( aResult
.isEmpty() )
563 OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
564 if ( !aDocumentName
.isEmpty() )
565 aResult
= GetFactoryNameByDocumentName( aDocumentName
);
572 OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
573 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
576 OUString aFilterName
;
578 for ( sal_Int32 nInd
= 0; nInd
< aMediaDescr
.getLength(); nInd
++ )
579 if ( aMediaDescr
[nInd
].Name
== "FilterName" )
580 aMediaDescr
[nInd
].Value
>>= aFilterName
;
582 if ( aFilterName
.isEmpty() )
584 // filter name is not specified, so type detection should be done
586 uno::Reference
< document::XTypeDetection
> xTypeDetection(
587 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext
),
590 if ( !xTypeDetection
.is() )
591 throw uno::RuntimeException(); // TODO
593 // typedetection can change the mode, add a stream and so on, thus a copy should be used
594 uno::Sequence
< beans::PropertyValue
> aTempMD( aMediaDescr
);
597 OUString aTypeName
= xTypeDetection
->queryTypeByDescriptor( aTempMD
, sal_True
);
600 for ( sal_Int32 nInd
= 0; nInd
< aTempMD
.getLength(); nInd
++ )
601 if ( aTempMD
[nInd
].Name
== "FilterName" )
602 aTempMD
[nInd
].Value
>>= aFilterName
;
604 if ( !aFilterName
.isEmpty() )
606 sal_Int32 nOldLen
= aMediaDescr
.getLength();
607 aMediaDescr
.realloc( nOldLen
+ 1 );
608 aMediaDescr
[nOldLen
].Name
= "FilterName";
609 aMediaDescr
[ nOldLen
].Value
<<= aFilterName
;
612 else if ( !aTypeName
.isEmpty() && !bIgnoreType
)
614 uno::Reference
< container::XNameAccess
> xNameAccess( xTypeDetection
, uno::UNO_QUERY
);
615 uno::Sequence
< beans::PropertyValue
> aTypes
;
617 if ( xNameAccess
.is() && ( xNameAccess
->getByName( aTypeName
) >>= aTypes
) )
619 for ( sal_Int32 nInd
= 0; nInd
< aTypes
.getLength(); nInd
++ )
621 if ( aTypes
[nInd
].Name
== "PreferredFilter" && ( aTypes
[nInd
].Value
>>= aFilterName
) )
623 sal_Int32 nOldLen
= aMediaDescr
.getLength();
624 aMediaDescr
.realloc( nOldLen
+ 1 );
625 aMediaDescr
[nOldLen
].Name
= "FilterName";
626 aMediaDescr
[ nOldLen
].Value
= aTypes
[nInd
].Value
;
637 OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
638 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
639 uno::Sequence
< beans::NamedValue
>& aObject
)
642 for ( sal_Int32 nInd
= 0; nInd
< aObject
.getLength(); nInd
++ )
643 if ( aObject
[nInd
].Name
== "ObjectDocumentServiceName" )
645 aObject
[nInd
].Value
>>= aDocName
;
649 OSL_ENSURE( !aDocName
.isEmpty(), "The name must exist at this point!\n" );
652 bool bNeedsAddition
= true;
653 for ( sal_Int32 nMedInd
= 0; nMedInd
< aMediaDescr
.getLength(); nMedInd
++ )
654 if ( aMediaDescr
[nMedInd
].Name
== "DocumentService" )
656 aMediaDescr
[nMedInd
].Value
<<= aDocName
;
657 bNeedsAddition
= false;
661 if ( bNeedsAddition
)
663 sal_Int32 nOldLen
= aMediaDescr
.getLength();
664 aMediaDescr
.realloc( nOldLen
+ 1 );
665 aMediaDescr
[nOldLen
].Name
= "DocumentService";
666 aMediaDescr
[nOldLen
].Value
<<= aDocName
;
669 return UpdateMediaDescriptorWithFilterName( aMediaDescr
, true );
674 SfxFilterFlags
MimeConfigurationHelper::GetFilterFlags( const OUString
& aFilterName
)
676 SfxFilterFlags nFlags
= SfxFilterFlags::NONE
;
679 if ( !aFilterName
.isEmpty() )
681 uno::Reference
< container::XNameAccess
> xFilterFactory(
683 uno::UNO_SET_THROW
);
685 uno::Any aFilterAny
= xFilterFactory
->getByName( aFilterName
);
686 uno::Sequence
< beans::PropertyValue
> aData
;
687 if ( aFilterAny
>>= aData
)
689 SequenceAsHashMap
aFilterHM( aData
);
690 nFlags
= static_cast<SfxFilterFlags
>(aFilterHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 ));
693 } catch( uno::Exception
& )
699 bool MimeConfigurationHelper::AddFilterNameCheckOwnFile(
700 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
)
702 OUString aFilterName
= UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_False
);
703 if ( !aFilterName
.isEmpty() )
705 SfxFilterFlags nFlags
= GetFilterFlags( aFilterName
);
706 // check the OWN flag
707 return bool(nFlags
& SfxFilterFlags::OWN
);
715 OUString
MimeConfigurationHelper::GetDefaultFilterFromServiceName( const OUString
& aServiceName
, sal_Int32 nVersion
)
719 if ( !aServiceName
.isEmpty() && nVersion
)
722 uno::Reference
< container::XContainerQuery
> xFilterQuery(
724 uno::UNO_QUERY_THROW
);
726 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
727 aSearchRequest
[0].Name
= "DocumentService";
728 aSearchRequest
[0].Value
<<= aServiceName
;
729 aSearchRequest
[1].Name
= "FileFormatVersion";
730 aSearchRequest
[1].Value
<<= nVersion
;
732 uno::Reference
< container::XEnumeration
> xFilterEnum
=
733 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
735 // use the first filter that is found
736 if ( xFilterEnum
.is() )
737 while ( xFilterEnum
->hasMoreElements() )
739 uno::Sequence
< beans::PropertyValue
> aProps
;
740 if ( xFilterEnum
->nextElement() >>= aProps
)
742 SequenceAsHashMap
aPropsHM( aProps
);
743 SfxFilterFlags nFlags
= static_cast<SfxFilterFlags
>(aPropsHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 ));
745 // that should be import, export, own filter and not a template filter ( TemplatePath flag )
746 SfxFilterFlags
const nRequired
= (SfxFilterFlags::OWN
747 // fdo#78159 for OOoXML, there is code to convert
748 // to ODF in OCommonEmbeddedObject::store*
749 // so accept it even though there's no export
750 | (SOFFICE_FILEFORMAT_60
== nVersion
? SfxFilterFlags::NONE
: SfxFilterFlags::EXPORT
)
751 | SfxFilterFlags::IMPORT
);
752 if ( ( ( nFlags
& nRequired
) == nRequired
) && !( nFlags
& SfxFilterFlags::TEMPLATEPATH
) )
754 // if there are more than one filter the preffered one should be used
755 // if there is no preffered filter the first one will be used
756 if ( aResult
.isEmpty() || ( nFlags
& SfxFilterFlags::PREFERED
) )
757 aResult
= aPropsHM
.getUnpackedValueOrDefault( "Name", OUString() );
758 if ( nFlags
& SfxFilterFlags::PREFERED
)
759 break; // the preferred filter was found
764 catch( uno::Exception
& )
771 OUString
MimeConfigurationHelper::GetExportFilterFromImportFilter( const OUString
& aImportFilterName
)
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
)
787 SequenceAsHashMap
aImpFilterHM( aImpData
);
788 SfxFilterFlags nFlags
= static_cast<SfxFilterFlags
>(aImpFilterHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 ));
790 if ( !( nFlags
& SfxFilterFlags::IMPORT
) )
792 OSL_FAIL( "This is no import filter!" );
793 throw uno::Exception();
796 if ( nFlags
& SfxFilterFlags::EXPORT
)
798 aExportFilterName
= aImportFilterName
;
802 OUString aDocumentServiceName
= aImpFilterHM
.getUnpackedValueOrDefault( "DocumentService", OUString() );
803 OUString aTypeName
= aImpFilterHM
.getUnpackedValueOrDefault( "Type", OUString() );
805 OSL_ENSURE( !aDocumentServiceName
.isEmpty() && !aTypeName
.isEmpty(), "Incomplete filter data!" );
806 if ( !(aDocumentServiceName
.isEmpty() || aTypeName
.isEmpty()) )
808 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
809 aSearchRequest
[0].Name
= "Type";
810 aSearchRequest
[0].Value
<<= aTypeName
;
811 aSearchRequest
[1].Name
= "DocumentService";
812 aSearchRequest
[1].Value
<<= aDocumentServiceName
;
814 uno::Sequence
< beans::PropertyValue
> aExportFilterProps
= SearchForFilter(
815 uno::Reference
< container::XContainerQuery
>( xFilterFactory
, uno::UNO_QUERY_THROW
),
817 SfxFilterFlags::EXPORT
,
818 SfxFilterFlags::INTERNAL
);
820 if ( aExportFilterProps
.getLength() )
822 SequenceAsHashMap
aExpPropsHM( aExportFilterProps
);
823 aExportFilterName
= aExpPropsHM
.getUnpackedValueOrDefault( "Name", OUString() );
830 catch( uno::Exception
& )
833 return aExportFilterName
;
838 uno::Sequence
< beans::PropertyValue
> MimeConfigurationHelper::SearchForFilter(
839 const uno::Reference
< container::XContainerQuery
>& xFilterQuery
,
840 const uno::Sequence
< beans::NamedValue
>& aSearchRequest
,
841 SfxFilterFlags nMustFlags
,
842 SfxFilterFlags nDontFlags
)
844 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
845 uno::Reference
< container::XEnumeration
> xFilterEnum
=
846 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
848 // the first default filter will be taken,
849 // if there is no filter with flag default the first acceptable filter will be taken
850 if ( xFilterEnum
.is() )
852 while ( xFilterEnum
->hasMoreElements() )
854 uno::Sequence
< beans::PropertyValue
> aProps
;
855 if ( xFilterEnum
->nextElement() >>= aProps
)
857 SequenceAsHashMap
aPropsHM( aProps
);
858 SfxFilterFlags nFlags
= static_cast<SfxFilterFlags
>(aPropsHM
.getUnpackedValueOrDefault("Flags",
860 if ( ( ( nFlags
& nMustFlags
) == nMustFlags
) && !( nFlags
& nDontFlags
) )
862 if ( ( nFlags
& SfxFilterFlags::DEFAULT
) == SfxFilterFlags::DEFAULT
)
864 aFilterProps
= aProps
;
867 else if ( !aFilterProps
.getLength() )
868 aFilterProps
= aProps
;
879 bool MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence
< sal_Int8
>& aClassID1
, const uno::Sequence
< sal_Int8
>& aClassID2
)
881 if ( aClassID1
.getLength() != aClassID2
.getLength() )
884 for ( sal_Int32 nInd
= 0; nInd
< aClassID1
.getLength(); nInd
++ )
885 if ( aClassID1
[nInd
] != aClassID2
[nInd
] )
892 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
893 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
894 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
896 uno::Sequence
< sal_Int8
> aResult( 16 );
897 aResult
[0] = (sal_Int8
)( n1
>> 24 );
898 aResult
[1] = (sal_Int8
)( ( n1
<< 8 ) >> 24 );
899 aResult
[2] = (sal_Int8
)( ( n1
<< 16 ) >> 24 );
900 aResult
[3] = (sal_Int8
)( ( n1
<< 24 ) >> 24 );
901 aResult
[4] = (sal_Int8
)( n2
>> 8 );
902 aResult
[5] = (sal_Int8
)( ( n2
<< 8 ) >> 8 );
903 aResult
[6] = (sal_Int8
)( n3
>> 8 );
904 aResult
[7] = (sal_Int8
)( ( n3
<< 8 ) >> 8 );
917 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */