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 <comphelper/fileformat.h>
26 #include <comphelper/mimeconfighelper.hxx>
27 #include <comphelper/processfactory.hxx>
28 #include <comphelper/classids.hxx>
29 #include <comphelper/sequenceashashmap.hxx>
30 #include <comphelper/documentconstants.hxx>
33 using namespace ::com::sun::star
;
34 using namespace comphelper
;
36 //-----------------------------------------------------------------------
37 MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference
< uno::XComponentContext
>& rxContext
)
38 : m_xContext( rxContext
)
40 if ( !m_xContext
.is() )
41 throw uno::RuntimeException();
44 //-----------------------------------------------------------------------
45 OUString
MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence
< sal_Int8
>& aClassID
)
49 if ( aClassID
.getLength() == 16 )
51 for ( sal_Int32 nInd
= 0; nInd
< aClassID
.getLength(); nInd
++ )
53 if ( nInd
== 4 || nInd
== 6 || nInd
== 8 || nInd
== 10 )
56 sal_Int32 nDigit1
= (sal_Int32
)( (sal_uInt8
)aClassID
[nInd
] / 16 );
57 sal_Int32 nDigit2
= (sal_uInt8
)aClassID
[nInd
] % 16;
58 aResult
+= OUString::valueOf( nDigit1
, 16 );
59 aResult
+= OUString::valueOf( nDigit2
, 16 );
66 //-----------------------------------------------------------------------
67 sal_uInt8
GetDigit_Impl( sal_Char aChar
)
69 if ( aChar
>= '0' && aChar
<= '9' )
71 else if ( aChar
>= 'a' && aChar
<= 'f' )
72 return aChar
- 'a' + 10;
73 else if ( aChar
>= 'A' && aChar
<= 'F' )
74 return aChar
- 'A' + 10;
79 //-----------------------------------------------------------------------
80 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassIDRepresentation( const OUString
& aClassID
)
82 sal_Int32 nLength
= aClassID
.getLength();
85 OString aCharClassID
= OUStringToOString( aClassID
, RTL_TEXTENCODING_ASCII_US
);
86 const sal_Char
* pString
= aCharClassID
.getStr();
89 uno::Sequence
< sal_Int8
> aResult( 16 );
91 sal_Int32 nStrPointer
= 0;
92 sal_Int32 nSeqInd
= 0;
93 while( nSeqInd
< 16 && nStrPointer
+ 1 < nLength
)
95 sal_uInt8 nDigit1
= GetDigit_Impl( pString
[nStrPointer
++] );
96 sal_uInt8 nDigit2
= GetDigit_Impl( pString
[nStrPointer
++] );
98 if ( nDigit1
> 15 || nDigit2
> 15 )
101 aResult
[nSeqInd
++] = (sal_Int8
)( nDigit1
* 16 + nDigit2
);
103 if ( nStrPointer
< nLength
&& pString
[nStrPointer
] == '-' )
107 if ( nSeqInd
== 16 && nStrPointer
== nLength
)
112 return uno::Sequence
< sal_Int8
>();
115 //-----------------------------------------------------------------------
116 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetConfigurationByPath( const OUString
& aPath
)
118 osl::MutexGuard
aGuard( m_aMutex
);
120 uno::Reference
< container::XNameAccess
> xConfig
;
124 if ( !m_xConfigProvider
.is() )
125 m_xConfigProvider
= configuration::theDefaultProvider::get( m_xContext
);
127 uno::Sequence
< uno::Any
> aArgs( 1 );
128 beans::PropertyValue aPathProp
;
129 aPathProp
.Name
= "nodepath";
130 aPathProp
.Value
<<= aPath
;
131 aArgs
[0] <<= aPathProp
;
133 xConfig
= uno::Reference
< container::XNameAccess
>(
134 m_xConfigProvider
->createInstanceWithArguments(
135 OUString( "com.sun.star.configuration.ConfigurationAccess" ),
139 catch( uno::Exception
& )
145 //-----------------------------------------------------------------------
146 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetObjConfiguration()
148 osl::MutexGuard
aGuard( m_aMutex
);
150 if ( !m_xObjectConfig
.is() )
151 m_xObjectConfig
= GetConfigurationByPath(
152 OUString( "/org.openoffice.Office.Embedding/Objects" ) );
154 return m_xObjectConfig
;
157 //-----------------------------------------------------------------------
158 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetVerbsConfiguration()
160 osl::MutexGuard
aGuard( m_aMutex
);
162 if ( !m_xVerbsConfig
.is() )
163 m_xVerbsConfig
= GetConfigurationByPath(
164 OUString( "/org.openoffice.Office.Embedding/Verbs" ));
166 return m_xVerbsConfig
;
169 //-----------------------------------------------------------------------
170 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetMediaTypeConfiguration()
172 osl::MutexGuard
aGuard( m_aMutex
);
174 if ( !m_xMediaTypeConfig
.is() )
175 m_xMediaTypeConfig
= GetConfigurationByPath(
176 OUString( "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations" ));
178 return m_xMediaTypeConfig
;
181 //-----------------------------------------------------------------------
182 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetFilterFactory()
184 osl::MutexGuard
aGuard( m_aMutex
);
186 if ( !m_xFilterFactory
.is() )
187 m_xFilterFactory
.set(
188 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", m_xContext
),
191 return m_xFilterFactory
;
194 //-------------------------------------------------------------------------
195 OUString
MimeConfigurationHelper::GetDocServiceNameFromFilter( const OUString
& aFilterName
)
197 OUString aDocServiceName
;
201 uno::Reference
< container::XNameAccess
> xFilterFactory(
203 uno::UNO_SET_THROW
);
205 uno::Any aFilterAnyData
= xFilterFactory
->getByName( aFilterName
);
206 uno::Sequence
< beans::PropertyValue
> aFilterData
;
207 if ( aFilterAnyData
>>= aFilterData
)
209 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
210 if ( aFilterData
[nInd
].Name
== "DocumentService" )
211 aFilterData
[nInd
].Value
>>= aDocServiceName
;
214 catch( uno::Exception
& )
217 return aDocServiceName
;
220 //-------------------------------------------------------------------------
221 OUString
MimeConfigurationHelper::GetDocServiceNameFromMediaType( const OUString
& aMediaType
)
223 uno::Reference
< container::XContainerQuery
> xTypeCFG(
224 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext
),
231 // make query for all types matching the properties
232 uno::Sequence
< beans::NamedValue
> aSeq( 1 );
233 aSeq
[0].Name
= "MediaType";
234 aSeq
[0].Value
<<= aMediaType
;
236 uno::Reference
< container::XEnumeration
> xEnum
= xTypeCFG
->createSubSetEnumerationByProperties( aSeq
);
237 while ( xEnum
->hasMoreElements() )
239 uno::Sequence
< beans::PropertyValue
> aType
;
240 if ( xEnum
->nextElement() >>= aType
)
242 for ( sal_Int32 nInd
= 0; nInd
< aType
.getLength(); nInd
++ )
244 OUString aFilterName
;
245 if ( aType
[nInd
].Name
== "PreferredFilter"
246 && ( aType
[nInd
].Value
>>= aFilterName
) && !aFilterName
.isEmpty() )
248 OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
249 if ( !aDocumentName
.isEmpty() )
250 return aDocumentName
;
256 catch( uno::Exception
& )
263 //-------------------------------------------------------------------------
264 sal_Bool
MimeConfigurationHelper::GetVerbByShortcut( const OUString
& aVerbShortcut
,
265 embed::VerbDescriptor
& aDescriptor
)
267 sal_Bool bResult
= sal_False
;
269 uno::Reference
< container::XNameAccess
> xVerbsConfig
= GetVerbsConfiguration();
270 uno::Reference
< container::XNameAccess
> xVerbsProps
;
273 if ( xVerbsConfig
.is() && ( xVerbsConfig
->getByName( aVerbShortcut
) >>= xVerbsProps
) && xVerbsProps
.is() )
275 embed::VerbDescriptor aTempDescr
;
276 if ( ( xVerbsProps
->getByName( OUString( "VerbID" ) ) >>= aTempDescr
.VerbID
)
277 && ( xVerbsProps
->getByName( OUString( "VerbUIName" ) ) >>= aTempDescr
.VerbName
)
278 && ( xVerbsProps
->getByName( OUString( "VerbFlags" ) ) >>= aTempDescr
.VerbFlags
)
279 && ( xVerbsProps
->getByName( OUString( "VerbAttributes" ) ) >>= aTempDescr
.VerbAttributes
) )
281 aDescriptor
= aTempDescr
;
286 catch( uno::Exception
& )
293 //-------------------------------------------------------------------------
294 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjPropsFromConfigEntry(
295 const uno::Sequence
< sal_Int8
>& aClassID
,
296 const uno::Reference
< container::XNameAccess
>& xObjectProps
)
298 uno::Sequence
< beans::NamedValue
> aResult
;
300 if ( aClassID
.getLength() == 16 )
304 uno::Sequence
< OUString
> aObjPropNames
= xObjectProps
->getElementNames();
306 aResult
.realloc( aObjPropNames
.getLength() + 1 );
307 aResult
[0].Name
= "ClassID";
308 aResult
[0].Value
<<= aClassID
;
310 for ( sal_Int32 nInd
= 0; nInd
< aObjPropNames
.getLength(); nInd
++ )
312 aResult
[nInd
+ 1].Name
= aObjPropNames
[nInd
];
314 if ( aObjPropNames
[nInd
] == "ObjectVerbs" )
316 uno::Sequence
< OUString
> aVerbShortcuts
;
317 if ( xObjectProps
->getByName( aObjPropNames
[nInd
] ) >>= aVerbShortcuts
)
319 uno::Sequence
< embed::VerbDescriptor
> aVerbDescriptors( aVerbShortcuts
.getLength() );
320 for ( sal_Int32 nVerbI
= 0; nVerbI
< aVerbShortcuts
.getLength(); nVerbI
++ )
321 if ( !GetVerbByShortcut( aVerbShortcuts
[nVerbI
], aVerbDescriptors
[nVerbI
] ) )
322 throw uno::RuntimeException();
324 aResult
[nInd
+1].Value
<<= aVerbDescriptors
;
327 throw uno::RuntimeException();
330 aResult
[nInd
+1].Value
= xObjectProps
->getByName( aObjPropNames
[nInd
] );
333 catch( uno::Exception
& )
335 aResult
.realloc( 0 );
342 //-----------------------------------------------------------------------
343 OUString
MimeConfigurationHelper::GetExplicitlyRegisteredObjClassID( const OUString
& aMediaType
)
345 OUString aStringClassID
;
347 uno::Reference
< container::XNameAccess
> xMediaTypeConfig
= GetMediaTypeConfiguration();
350 if ( xMediaTypeConfig
.is() )
351 xMediaTypeConfig
->getByName( aMediaType
) >>= aStringClassID
;
353 catch( uno::Exception
& )
357 return aStringClassID
;
361 //-----------------------------------------------------------------------
362 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByStringClassID(
363 const OUString
& aStringClassID
)
365 uno::Sequence
< beans::NamedValue
> aObjProps
;
367 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
368 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
370 aObjProps
.realloc(2);
371 aObjProps
[0].Name
= "ObjectFactory";
372 aObjProps
[0].Value
<<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
373 aObjProps
[1].Name
= "ClassID";
374 aObjProps
[1].Value
<<= aClassID
;
378 if ( aClassID
.getLength() == 16 )
380 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
381 uno::Reference
< container::XNameAccess
> xObjectProps
;
384 // TODO/LATER: allow to provide ClassID string in any format, only digits are counted
385 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
386 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
388 catch( uno::Exception
& )
396 //-----------------------------------------------------------------------
397 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByClassID(
398 const uno::Sequence
< sal_Int8
>& aClassID
)
400 uno::Sequence
< beans::NamedValue
> aObjProps
;
401 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
403 aObjProps
.realloc(2);
404 aObjProps
[0].Name
= "ObjectFactory";
405 aObjProps
[0].Value
<<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
406 aObjProps
[1].Name
= "ClassID";
407 aObjProps
[1].Value
<<= aClassID
;
410 OUString aStringClassID
= GetStringClassIDRepresentation( aClassID
);
411 if ( !aStringClassID
.isEmpty() )
413 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
414 uno::Reference
< container::XNameAccess
> xObjectProps
;
417 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
418 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
420 catch( uno::Exception
& )
428 //-----------------------------------------------------------------------
429 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByMediaType( const OUString
& aMediaType
)
431 uno::Sequence
< beans::NamedValue
> aObject
=
432 GetObjectPropsByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
433 if ( aObject
.getLength() )
436 OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
437 if ( !aDocumentName
.isEmpty() )
438 return GetObjectPropsByDocumentName( aDocumentName
);
440 return uno::Sequence
< beans::NamedValue
>();
443 //-----------------------------------------------------------------------
444 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByFilter( const OUString
& aFilterName
)
446 OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
447 if ( !aDocumentName
.isEmpty() )
448 return GetObjectPropsByDocumentName( aDocumentName
);
450 return uno::Sequence
< beans::NamedValue
>();
453 //-----------------------------------------------------------------------
454 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByDocumentName( const OUString
& aDocName
)
456 if ( !aDocName
.isEmpty() )
458 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
459 if ( xObjConfig
.is() )
463 uno::Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
464 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
466 uno::Reference
< container::XNameAccess
> xObjectProps
;
467 OUString aEntryDocName
;
469 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
470 && ( xObjectProps
->getByName( OUString( "ObjectDocumentServiceName" ) ) >>= aEntryDocName
)
471 && aEntryDocName
== aDocName
)
473 return GetObjPropsFromConfigEntry( GetSequenceClassIDRepresentation( aClassIDs
[nInd
] ),
478 catch( uno::Exception
& )
483 return uno::Sequence
< beans::NamedValue
>();
486 //-----------------------------------------------------------------------
487 OUString
MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence
< sal_Int8
>& aClassID
)
489 return GetFactoryNameByStringClassID( GetStringClassIDRepresentation( aClassID
) );
492 //-----------------------------------------------------------------------
493 OUString
MimeConfigurationHelper::GetFactoryNameByStringClassID( const OUString
& aStringClassID
)
497 if ( !aStringClassID
.isEmpty() )
499 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
500 uno::Reference
< container::XNameAccess
> xObjectProps
;
503 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
504 xObjectProps
->getByName( OUString( "ObjectFactory" ) ) >>= aResult
;
506 catch( uno::Exception
& )
508 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
509 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
510 return OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
517 //-----------------------------------------------------------------------
518 OUString
MimeConfigurationHelper::GetFactoryNameByDocumentName( const OUString
& aDocName
)
522 if ( !aDocName
.isEmpty() )
524 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
525 if ( xObjConfig
.is() )
529 uno::Sequence
< OUString
> aClassIDs
= xObjConfig
->getElementNames();
530 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
532 uno::Reference
< container::XNameAccess
> xObjectProps
;
533 OUString aEntryDocName
;
535 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
536 && ( xObjectProps
->getByName(
537 OUString( "ObjectDocumentServiceName" ) ) >>= aEntryDocName
)
538 && aEntryDocName
== aDocName
)
540 xObjectProps
->getByName( OUString( "ObjectFactory" ) ) >>= aResult
;
545 catch( uno::Exception
& )
554 //-----------------------------------------------------------------------
555 OUString
MimeConfigurationHelper::GetFactoryNameByMediaType( const OUString
& aMediaType
)
557 OUString aResult
= GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
559 if ( aResult
.isEmpty() )
561 OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
562 if ( !aDocumentName
.isEmpty() )
563 aResult
= GetFactoryNameByDocumentName( aDocumentName
);
569 //-----------------------------------------------------------------------
570 OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
571 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
572 sal_Bool bIgnoreType
)
574 OUString aFilterName
;
576 for ( sal_Int32 nInd
= 0; nInd
< aMediaDescr
.getLength(); nInd
++ )
577 if ( aMediaDescr
[nInd
].Name
== "FilterName" )
578 aMediaDescr
[nInd
].Value
>>= aFilterName
;
580 if ( aFilterName
.isEmpty() )
582 // filter name is not specified, so type detection should be done
584 uno::Reference
< document::XTypeDetection
> xTypeDetection(
585 m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext
),
588 if ( !xTypeDetection
.is() )
589 throw uno::RuntimeException(); // TODO
591 // typedetection can change the mode, add a stream and so on, thus a copy should be used
592 uno::Sequence
< beans::PropertyValue
> aTempMD( aMediaDescr
);
595 OUString aTypeName
= xTypeDetection
->queryTypeByDescriptor( aTempMD
, sal_True
);
598 for ( sal_Int32 nInd
= 0; nInd
< aTempMD
.getLength(); nInd
++ )
599 if ( aTempMD
[nInd
].Name
== "FilterName" )
600 aTempMD
[nInd
].Value
>>= aFilterName
;
602 if ( !aFilterName
.isEmpty() )
604 sal_Int32 nOldLen
= aMediaDescr
.getLength();
605 aMediaDescr
.realloc( nOldLen
+ 1 );
606 aMediaDescr
[nOldLen
].Name
= "FilterName";
607 aMediaDescr
[ nOldLen
].Value
<<= aFilterName
;
610 else if ( !aTypeName
.isEmpty() && !bIgnoreType
)
612 uno::Reference
< container::XNameAccess
> xNameAccess( xTypeDetection
, uno::UNO_QUERY
);
613 uno::Sequence
< beans::PropertyValue
> aTypes
;
615 if ( xNameAccess
.is() && ( xNameAccess
->getByName( aTypeName
) >>= aTypes
) )
617 for ( sal_Int32 nInd
= 0; nInd
< aTypes
.getLength(); nInd
++ )
619 if ( aTypes
[nInd
].Name
== "PreferredFilter" && ( aTypes
[nInd
].Value
>>= aFilterName
) )
621 sal_Int32 nOldLen
= aMediaDescr
.getLength();
622 aMediaDescr
.realloc( nOldLen
+ 1 );
623 aMediaDescr
[nOldLen
].Name
= "FilterName";
624 aMediaDescr
[ nOldLen
].Value
= aTypes
[nInd
].Value
;
635 OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
636 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
637 uno::Sequence
< beans::NamedValue
>& aObject
)
640 for ( sal_Int32 nInd
= 0; nInd
< aObject
.getLength(); nInd
++ )
641 if ( aObject
[nInd
].Name
== "ObjectDocumentServiceName" )
643 aObject
[nInd
].Value
>>= aDocName
;
647 OSL_ENSURE( !aDocName
.isEmpty(), "The name must exist at this point!\n" );
650 sal_Bool bNeedsAddition
= sal_True
;
651 for ( sal_Int32 nMedInd
= 0; nMedInd
< aMediaDescr
.getLength(); nMedInd
++ )
652 if ( aMediaDescr
[nMedInd
].Name
== "DocumentService" )
654 aMediaDescr
[nMedInd
].Value
<<= aDocName
;
655 bNeedsAddition
= sal_False
;
659 if ( bNeedsAddition
)
661 sal_Int32 nOldLen
= aMediaDescr
.getLength();
662 aMediaDescr
.realloc( nOldLen
+ 1 );
663 aMediaDescr
[nOldLen
].Name
= "DocumentService";
664 aMediaDescr
[nOldLen
].Value
<<= aDocName
;
667 return UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_True
);
672 sal_Int32
MimeConfigurationHelper::GetFilterFlags( const OUString
& aFilterName
)
674 sal_Int32 nFlags
= 0;
677 if ( !aFilterName
.isEmpty() )
679 uno::Reference
< container::XNameAccess
> xFilterFactory(
681 uno::UNO_SET_THROW
);
683 uno::Any aFilterAny
= xFilterFactory
->getByName( aFilterName
);
684 uno::Sequence
< beans::PropertyValue
> aData
;
685 if ( aFilterAny
>>= aData
)
687 SequenceAsHashMap
aFilterHM( aData
);
688 nFlags
= aFilterHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 );
691 } catch( uno::Exception
& )
697 sal_Bool
MimeConfigurationHelper::AddFilterNameCheckOwnFile(
698 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
)
700 sal_Bool bResult
= sal_False
;
702 OUString aFilterName
= UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_False
);
703 if ( !aFilterName
.isEmpty() )
705 sal_Int32 nFlags
= GetFilterFlags( aFilterName
);
706 // check the OWN flag
707 bResult
= ( nFlags
& SFX_FILTER_OWN
);
714 //-----------------------------------------------------------
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::Sequence
< beans::PropertyValue
> aFilterProps
;
733 uno::Reference
< container::XEnumeration
> xFilterEnum
=
734 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
736 // use the first filter that is found
737 if ( xFilterEnum
.is() )
738 while ( xFilterEnum
->hasMoreElements() )
740 uno::Sequence
< beans::PropertyValue
> aProps
;
741 if ( xFilterEnum
->nextElement() >>= aProps
)
743 SequenceAsHashMap
aPropsHM( aProps
);
744 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 );
746 // that should be import, export, own filter and not a template filter ( TemplatePath flag )
747 sal_Int32 nRequired
= ( SFX_FILTER_OWN
| SFX_FILTER_EXPORT
| SFX_FILTER_IMPORT
);
748 if ( ( ( nFlags
& nRequired
) == nRequired
) && !( nFlags
& SFX_FILTER_TEMPLATEPATH
) )
750 // if there are more than one filter the preffered one should be used
751 // if there is no preffered filter the first one will be used
752 if ( aResult
.isEmpty() || ( nFlags
& SFX_FILTER_PREFERED
) )
753 aResult
= aPropsHM
.getUnpackedValueOrDefault( "Name", OUString() );
754 if ( nFlags
& SFX_FILTER_PREFERED
)
755 break; // the preferred filter was found
760 catch( uno::Exception
& )
766 //-------------------------------------------------------------------------
767 OUString
MimeConfigurationHelper::GetExportFilterFromImportFilter( const OUString
& aImportFilterName
)
769 OUString aExportFilterName
;
773 if ( !aImportFilterName
.isEmpty() )
775 uno::Reference
< container::XNameAccess
> xFilterFactory(
777 uno::UNO_SET_THROW
);
779 uno::Any aImpFilterAny
= xFilterFactory
->getByName( aImportFilterName
);
780 uno::Sequence
< beans::PropertyValue
> aImpData
;
781 if ( aImpFilterAny
>>= aImpData
)
783 SequenceAsHashMap
aImpFilterHM( aImpData
);
784 sal_Int32 nFlags
= aImpFilterHM
.getUnpackedValueOrDefault( "Flags", (sal_Int32
)0 );
786 if ( !( nFlags
& SFX_FILTER_IMPORT
) )
788 OSL_FAIL( "This is no import filter!" );
789 throw uno::Exception();
792 if ( nFlags
& SFX_FILTER_EXPORT
)
794 aExportFilterName
= aImportFilterName
;
798 OUString aDocumentServiceName
= aImpFilterHM
.getUnpackedValueOrDefault( "DocumentService", OUString() );
799 OUString aTypeName
= aImpFilterHM
.getUnpackedValueOrDefault( "Type", OUString() );
801 OSL_ENSURE( !aDocumentServiceName
.isEmpty() && !aTypeName
.isEmpty(), "Incomplete filter data!" );
802 if ( !(aDocumentServiceName
.isEmpty() || aTypeName
.isEmpty()) )
804 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
805 aSearchRequest
[0].Name
= "Type";
806 aSearchRequest
[0].Value
<<= aTypeName
;
807 aSearchRequest
[1].Name
= "DocumentService";
808 aSearchRequest
[1].Value
<<= aDocumentServiceName
;
810 uno::Sequence
< beans::PropertyValue
> aExportFilterProps
= SearchForFilter(
811 uno::Reference
< container::XContainerQuery
>( xFilterFactory
, uno::UNO_QUERY_THROW
),
814 SFX_FILTER_INTERNAL
);
816 if ( aExportFilterProps
.getLength() )
818 SequenceAsHashMap
aExpPropsHM( aExportFilterProps
);
819 aExportFilterName
= aExpPropsHM
.getUnpackedValueOrDefault( "Name", OUString() );
826 catch( uno::Exception
& )
829 return aExportFilterName
;
832 //-------------------------------------------------------------------------
834 uno::Sequence
< beans::PropertyValue
> MimeConfigurationHelper::SearchForFilter(
835 const uno::Reference
< container::XContainerQuery
>& xFilterQuery
,
836 const uno::Sequence
< beans::NamedValue
>& aSearchRequest
,
837 sal_Int32 nMustFlags
,
838 sal_Int32 nDontFlags
)
840 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
841 uno::Reference
< container::XEnumeration
> xFilterEnum
=
842 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
844 // the first default filter will be taken,
845 // if there is no filter with flag default the first acceptable filter will be taken
846 if ( xFilterEnum
.is() )
848 while ( xFilterEnum
->hasMoreElements() )
850 uno::Sequence
< beans::PropertyValue
> aProps
;
851 if ( xFilterEnum
->nextElement() >>= aProps
)
853 SequenceAsHashMap
aPropsHM( aProps
);
854 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( OUString("Flags"),
856 if ( ( ( nFlags
& nMustFlags
) == nMustFlags
) && !( nFlags
& nDontFlags
) )
858 if ( ( nFlags
& SFX_FILTER_DEFAULT
) == SFX_FILTER_DEFAULT
)
860 aFilterProps
= aProps
;
863 else if ( !aFilterProps
.getLength() )
864 aFilterProps
= aProps
;
874 //-------------------------------------------------------------------------
875 sal_Bool
MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence
< sal_Int8
>& aClassID1
, const uno::Sequence
< sal_Int8
>& aClassID2
)
877 if ( aClassID1
.getLength() != aClassID2
.getLength() )
880 for ( sal_Int32 nInd
= 0; nInd
< aClassID1
.getLength(); nInd
++ )
881 if ( aClassID1
[nInd
] != aClassID2
[nInd
] )
887 //-------------------------------------------------------------------------
888 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
889 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
890 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
892 uno::Sequence
< sal_Int8
> aResult( 16 );
893 aResult
[0] = (sal_Int8
)( n1
>> 24 );
894 aResult
[1] = (sal_Int8
)( ( n1
<< 8 ) >> 24 );
895 aResult
[2] = (sal_Int8
)( ( n1
<< 16 ) >> 24 );
896 aResult
[3] = (sal_Int8
)( ( n1
<< 24 ) >> 24 );
897 aResult
[4] = (sal_Int8
)( n2
>> 8 );
898 aResult
[5] = (sal_Int8
)( ( n2
<< 8 ) >> 8 );
899 aResult
[6] = (sal_Int8
)( n3
>> 8 );
900 aResult
[7] = (sal_Int8
)( ( n3
<< 8 ) >> 8 );
913 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */