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
< lang::XMultiServiceFactory
>& xFactory
)
38 : m_xFactory( xFactory
)
40 if ( !m_xFactory
.is() )
41 throw uno::RuntimeException();
44 //-----------------------------------------------------------------------
45 ::rtl::OUString
MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence
< sal_Int8
>& aClassID
)
47 ::rtl::OUString aResult
;
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 )
54 aResult
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "-" ));
56 sal_Int32 nDigit1
= (sal_Int32
)( (sal_uInt8
)aClassID
[nInd
] / 16 );
57 sal_Int32 nDigit2
= (sal_uInt8
)aClassID
[nInd
] % 16;
58 aResult
+= ::rtl::OUString::valueOf( nDigit1
, 16 );
59 aResult
+= ::rtl::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 ::rtl::OUString
& aClassID
)
82 sal_Int32 nLength
= aClassID
.getLength();
85 ::rtl::OString aCharClassID
= ::rtl::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 ::rtl::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(
126 getComponentContext( m_xFactory
) );
128 uno::Sequence
< uno::Any
> aArgs( 1 );
129 beans::PropertyValue aPathProp
;
130 aPathProp
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
131 aPathProp
.Value
<<= aPath
;
132 aArgs
[0] <<= aPathProp
;
134 xConfig
= uno::Reference
< container::XNameAccess
>(
135 m_xConfigProvider
->createInstanceWithArguments(
136 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )),
140 catch( uno::Exception
& )
146 //-----------------------------------------------------------------------
147 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetObjConfiguration()
149 osl::MutexGuard
aGuard( m_aMutex
);
151 if ( !m_xObjectConfig
.is() )
152 m_xObjectConfig
= GetConfigurationByPath(
153 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/Objects" )) );
155 return m_xObjectConfig
;
158 //-----------------------------------------------------------------------
159 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetVerbsConfiguration()
161 osl::MutexGuard
aGuard( m_aMutex
);
163 if ( !m_xVerbsConfig
.is() )
164 m_xVerbsConfig
= GetConfigurationByPath(
165 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/Verbs" )) );
167 return m_xVerbsConfig
;
170 //-----------------------------------------------------------------------
171 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetMediaTypeConfiguration()
173 osl::MutexGuard
aGuard( m_aMutex
);
175 if ( !m_xMediaTypeConfig
.is() )
176 m_xMediaTypeConfig
= GetConfigurationByPath(
177 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations" )) );
179 return m_xMediaTypeConfig
;
182 //-----------------------------------------------------------------------
183 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetFilterFactory()
185 osl::MutexGuard
aGuard( m_aMutex
);
187 if ( !m_xFilterFactory
.is() )
188 m_xFilterFactory
.set(
189 m_xFactory
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.FilterFactory")) ),
192 return m_xFilterFactory
;
195 //-------------------------------------------------------------------------
196 ::rtl::OUString
MimeConfigurationHelper::GetDocServiceNameFromFilter( const ::rtl::OUString
& aFilterName
)
198 ::rtl::OUString aDocServiceName
;
202 uno::Reference
< container::XNameAccess
> xFilterFactory(
204 uno::UNO_SET_THROW
);
206 uno::Any aFilterAnyData
= xFilterFactory
->getByName( aFilterName
);
207 uno::Sequence
< beans::PropertyValue
> aFilterData
;
208 if ( aFilterAnyData
>>= aFilterData
)
210 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
211 if ( aFilterData
[nInd
].Name
== "DocumentService" )
212 aFilterData
[nInd
].Value
>>= aDocServiceName
;
215 catch( uno::Exception
& )
218 return aDocServiceName
;
221 //-------------------------------------------------------------------------
222 ::rtl::OUString
MimeConfigurationHelper::GetDocServiceNameFromMediaType( const ::rtl::OUString
& aMediaType
)
224 uno::Reference
< container::XContainerQuery
> xTypeCFG(
225 m_xFactory
->createInstance(
226 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) ),
233 // make query for all types matching the properties
234 uno::Sequence
< beans::NamedValue
> aSeq( 1 );
235 aSeq
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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 ::rtl::OUString aFilterName
;
247 if ( aType
[nInd
].Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PreferredFilter" ) )
248 && ( aType
[nInd
].Value
>>= aFilterName
) && !aFilterName
.isEmpty() )
250 ::rtl::OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
251 if ( !aDocumentName
.isEmpty() )
252 return aDocumentName
;
258 catch( uno::Exception
& )
262 return ::rtl::OUString();
265 //-------------------------------------------------------------------------
266 sal_Bool
MimeConfigurationHelper::GetVerbByShortcut( const ::rtl::OUString
& aVerbShortcut
,
267 embed::VerbDescriptor
& aDescriptor
)
269 sal_Bool bResult
= sal_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( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbID" )) ) >>= aTempDescr
.VerbID
)
279 && ( xVerbsProps
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbUIName" )) ) >>= aTempDescr
.VerbName
)
280 && ( xVerbsProps
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbFlags" )) ) >>= aTempDescr
.VerbFlags
)
281 && ( xVerbsProps
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VerbAttributes" )) ) >>= aTempDescr
.VerbAttributes
) )
283 aDescriptor
= aTempDescr
;
288 catch( uno::Exception
& )
295 //-------------------------------------------------------------------------
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
< ::rtl::OUString
> aObjPropNames
= xObjectProps
->getElementNames();
308 aResult
.realloc( aObjPropNames
.getLength() + 1 );
309 aResult
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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
< ::rtl::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 );
344 //-----------------------------------------------------------------------
345 ::rtl::OUString
MimeConfigurationHelper::GetExplicitlyRegisteredObjClassID( const ::rtl::OUString
& aMediaType
)
347 ::rtl::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
;
363 //-----------------------------------------------------------------------
364 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByStringClassID(
365 const ::rtl::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
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" ));
374 aObjProps
[0].Value
<<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" ));
375 aObjProps
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "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
& )
398 //-----------------------------------------------------------------------
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
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" ));
407 aObjProps
[0].Value
<<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" ));
408 aObjProps
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ClassID" ));
409 aObjProps
[1].Value
<<= aClassID
;
412 ::rtl::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
& )
430 //-----------------------------------------------------------------------
431 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByMediaType( const ::rtl::OUString
& aMediaType
)
433 uno::Sequence
< beans::NamedValue
> aObject
=
434 GetObjectPropsByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
435 if ( aObject
.getLength() )
438 ::rtl::OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
439 if ( !aDocumentName
.isEmpty() )
440 return GetObjectPropsByDocumentName( aDocumentName
);
442 return uno::Sequence
< beans::NamedValue
>();
445 //-----------------------------------------------------------------------
446 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByFilter( const ::rtl::OUString
& aFilterName
)
448 ::rtl::OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
449 if ( !aDocumentName
.isEmpty() )
450 return GetObjectPropsByDocumentName( aDocumentName
);
452 return uno::Sequence
< beans::NamedValue
>();
455 //-----------------------------------------------------------------------
456 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByDocumentName( const ::rtl::OUString
& aDocName
)
458 if ( !aDocName
.isEmpty() )
460 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
461 if ( xObjConfig
.is() )
465 uno::Sequence
< ::rtl::OUString
> aClassIDs
= xObjConfig
->getElementNames();
466 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
468 uno::Reference
< container::XNameAccess
> xObjectProps
;
469 ::rtl::OUString aEntryDocName
;
471 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
472 && ( xObjectProps
->getByName(
473 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectDocumentServiceName" )) ) >>= aEntryDocName
)
474 && aEntryDocName
.equals( aDocName
) )
476 return GetObjPropsFromConfigEntry( GetSequenceClassIDRepresentation( aClassIDs
[nInd
] ),
481 catch( uno::Exception
& )
486 return uno::Sequence
< beans::NamedValue
>();
489 //-----------------------------------------------------------------------
490 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence
< sal_Int8
>& aClassID
)
492 return GetFactoryNameByStringClassID( GetStringClassIDRepresentation( aClassID
) );
495 //-----------------------------------------------------------------------
496 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByStringClassID( const ::rtl::OUString
& aStringClassID
)
498 ::rtl::OUString aResult
;
500 if ( !aStringClassID
.isEmpty() )
502 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
503 uno::Reference
< container::XNameAccess
> xObjectProps
;
506 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
507 xObjectProps
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )) ) >>= aResult
;
509 catch( uno::Exception
& )
511 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
512 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
513 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" ));
520 //-----------------------------------------------------------------------
521 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByDocumentName( const ::rtl::OUString
& aDocName
)
523 ::rtl::OUString aResult
;
525 if ( !aDocName
.isEmpty() )
527 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
528 if ( xObjConfig
.is() )
532 uno::Sequence
< ::rtl::OUString
> aClassIDs
= xObjConfig
->getElementNames();
533 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
535 uno::Reference
< container::XNameAccess
> xObjectProps
;
536 ::rtl::OUString aEntryDocName
;
538 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
539 && ( xObjectProps
->getByName(
540 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectDocumentServiceName" )) ) >>= aEntryDocName
)
541 && aEntryDocName
.equals( aDocName
) )
543 xObjectProps
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ObjectFactory" )) ) >>= aResult
;
548 catch( uno::Exception
& )
557 //-----------------------------------------------------------------------
558 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByMediaType( const ::rtl::OUString
& aMediaType
)
560 ::rtl::OUString aResult
= GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
562 if ( aResult
.isEmpty() )
564 ::rtl::OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
565 if ( !aDocumentName
.isEmpty() )
566 aResult
= GetFactoryNameByDocumentName( aDocumentName
);
572 //-----------------------------------------------------------------------
573 ::rtl::OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
574 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
575 sal_Bool bIgnoreType
)
577 ::rtl::OUString aFilterName
;
579 for ( sal_Int32 nInd
= 0; nInd
< aMediaDescr
.getLength(); nInd
++ )
580 if ( aMediaDescr
[nInd
].Name
== "FilterName" )
581 aMediaDescr
[nInd
].Value
>>= aFilterName
;
583 if ( aFilterName
.isEmpty() )
585 // filter name is not specified, so type detection should be done
587 uno::Reference
< document::XTypeDetection
> xTypeDetection(
588 m_xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.TypeDetection" )) ),
591 if ( !xTypeDetection
.is() )
592 throw uno::RuntimeException(); // TODO
594 // typedetection can change the mode, add a stream and so on, thus a copy should be used
595 uno::Sequence
< beans::PropertyValue
> aTempMD( aMediaDescr
);
598 ::rtl::OUString aTypeName
= xTypeDetection
->queryTypeByDescriptor( aTempMD
, sal_True
);
601 for ( sal_Int32 nInd
= 0; nInd
< aTempMD
.getLength(); nInd
++ )
602 if ( aTempMD
[nInd
].Name
== "FilterName" )
603 aTempMD
[nInd
].Value
>>= aFilterName
;
605 if ( !aFilterName
.isEmpty() )
607 sal_Int32 nOldLen
= aMediaDescr
.getLength();
608 aMediaDescr
.realloc( nOldLen
+ 1 );
609 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
610 aMediaDescr
[ nOldLen
].Value
<<= aFilterName
;
613 else if ( !aTypeName
.isEmpty() && !bIgnoreType
)
615 uno::Reference
< container::XNameAccess
> xNameAccess( xTypeDetection
, uno::UNO_QUERY
);
616 uno::Sequence
< beans::PropertyValue
> aTypes
;
618 if ( xNameAccess
.is() && ( xNameAccess
->getByName( aTypeName
) >>= aTypes
) )
620 for ( sal_Int32 nInd
= 0; nInd
< aTypes
.getLength(); nInd
++ )
622 if ( aTypes
[nInd
].Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PreferredFilter" ) ) && ( aTypes
[nInd
].Value
>>= aFilterName
) )
624 sal_Int32 nOldLen
= aMediaDescr
.getLength();
625 aMediaDescr
.realloc( nOldLen
+ 1 );
626 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
627 aMediaDescr
[ nOldLen
].Value
= aTypes
[nInd
].Value
;
638 ::rtl::OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
639 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
640 uno::Sequence
< beans::NamedValue
>& aObject
)
642 ::rtl::OUString aDocName
;
643 for ( sal_Int32 nInd
= 0; nInd
< aObject
.getLength(); nInd
++ )
644 if ( aObject
[nInd
].Name
== "ObjectDocumentServiceName" )
646 aObject
[nInd
].Value
>>= aDocName
;
650 OSL_ENSURE( !aDocName
.isEmpty(), "The name must exist at this point!\n" );
653 sal_Bool bNeedsAddition
= sal_True
;
654 for ( sal_Int32 nMedInd
= 0; nMedInd
< aMediaDescr
.getLength(); nMedInd
++ )
655 if ( aMediaDescr
[nMedInd
].Name
== "DocumentService" )
657 aMediaDescr
[nMedInd
].Value
<<= aDocName
;
658 bNeedsAddition
= sal_False
;
662 if ( bNeedsAddition
)
664 sal_Int32 nOldLen
= aMediaDescr
.getLength();
665 aMediaDescr
.realloc( nOldLen
+ 1 );
666 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ));
667 aMediaDescr
[nOldLen
].Value
<<= aDocName
;
670 return UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_True
);
675 sal_Int32
MimeConfigurationHelper::GetFilterFlags( const ::rtl::OUString
& aFilterName
)
677 sal_Int32 nFlags
= 0;
680 if ( !aFilterName
.isEmpty() )
682 uno::Reference
< container::XNameAccess
> xFilterFactory(
684 uno::UNO_SET_THROW
);
686 uno::Any aFilterAny
= xFilterFactory
->getByName( aFilterName
);
687 uno::Sequence
< beans::PropertyValue
> aData
;
688 if ( aFilterAny
>>= aData
)
690 SequenceAsHashMap
aFilterHM( aData
);
691 nFlags
= aFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")), (sal_Int32
)0 );
694 } catch( uno::Exception
& )
700 sal_Bool
MimeConfigurationHelper::AddFilterNameCheckOwnFile(
701 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
)
703 sal_Bool bResult
= sal_False
;
705 ::rtl::OUString aFilterName
= UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_False
);
706 if ( !aFilterName
.isEmpty() )
708 sal_Int32 nFlags
= GetFilterFlags( aFilterName
);
709 // check the OWN flag
710 bResult
= ( nFlags
& SFX_FILTER_OWN
);
717 //-----------------------------------------------------------
718 ::rtl::OUString
MimeConfigurationHelper::GetDefaultFilterFromServiceName( const ::rtl::OUString
& aServiceName
, sal_Int32 nVersion
)
720 rtl::OUString aResult
;
722 if ( !aServiceName
.isEmpty() && nVersion
)
725 uno::Reference
< container::XContainerQuery
> xFilterQuery(
727 uno::UNO_QUERY_THROW
);
729 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
730 aSearchRequest
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ));
731 aSearchRequest
[0].Value
<<= aServiceName
;
732 aSearchRequest
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileFormatVersion" ));
733 aSearchRequest
[1].Value
<<= nVersion
;
735 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
736 uno::Reference
< container::XEnumeration
> xFilterEnum
=
737 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
739 // use the first filter that is found
740 if ( xFilterEnum
.is() )
741 while ( xFilterEnum
->hasMoreElements() )
743 uno::Sequence
< beans::PropertyValue
> aProps
;
744 if ( xFilterEnum
->nextElement() >>= aProps
)
746 SequenceAsHashMap
aPropsHM( aProps
);
747 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Flags" )),
750 // that should be import, export, own filter and not a template filter ( TemplatePath flag )
751 sal_Int32 nRequired
= ( SFX_FILTER_OWN
| SFX_FILTER_EXPORT
| SFX_FILTER_IMPORT
);
752 if ( ( ( nFlags
& nRequired
) == nRequired
) && !( nFlags
& SFX_FILTER_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
& SFX_FILTER_PREFERED
) )
757 aResult
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" )),
759 if ( nFlags
& SFX_FILTER_PREFERED
)
760 break; // the preffered filter was found
765 catch( uno::Exception
& )
771 //-------------------------------------------------------------------------
772 ::rtl::OUString
MimeConfigurationHelper::GetExportFilterFromImportFilter( const ::rtl::OUString
& aImportFilterName
)
774 ::rtl::OUString aExportFilterName
;
778 if ( !aImportFilterName
.isEmpty() )
780 uno::Reference
< container::XNameAccess
> xFilterFactory(
782 uno::UNO_SET_THROW
);
784 uno::Any aImpFilterAny
= xFilterFactory
->getByName( aImportFilterName
);
785 uno::Sequence
< beans::PropertyValue
> aImpData
;
786 if ( aImpFilterAny
>>= aImpData
)
788 SequenceAsHashMap
aImpFilterHM( aImpData
);
789 sal_Int32 nFlags
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")),
792 if ( !( nFlags
& SFX_FILTER_IMPORT
) )
794 OSL_FAIL( "This is no import filter!" );
795 throw uno::Exception();
798 if ( nFlags
& SFX_FILTER_EXPORT
)
800 aExportFilterName
= aImportFilterName
;
804 ::rtl::OUString aDocumentServiceName
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService")), ::rtl::OUString() );
805 ::rtl::OUString aTypeName
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type")), ::rtl::OUString() );
807 OSL_ENSURE( !aDocumentServiceName
.isEmpty() && !aTypeName
.isEmpty(), "Incomplete filter data!" );
808 if ( !(aDocumentServiceName
.isEmpty() || aTypeName
.isEmpty()) )
810 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
811 aSearchRequest
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Type"));
812 aSearchRequest
[0].Value
<<= aTypeName
;
813 aSearchRequest
[1].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentService"));
814 aSearchRequest
[1].Value
<<= aDocumentServiceName
;
816 uno::Sequence
< beans::PropertyValue
> aExportFilterProps
= SearchForFilter(
817 uno::Reference
< container::XContainerQuery
>( xFilterFactory
, uno::UNO_QUERY_THROW
),
820 SFX_FILTER_INTERNAL
);
822 if ( aExportFilterProps
.getLength() )
824 SequenceAsHashMap
aExpPropsHM( aExportFilterProps
);
825 aExportFilterName
= aExpPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), ::rtl::OUString() );
832 catch( uno::Exception
& )
835 return aExportFilterName
;
838 //-------------------------------------------------------------------------
840 uno::Sequence
< beans::PropertyValue
> MimeConfigurationHelper::SearchForFilter(
841 const uno::Reference
< container::XContainerQuery
>& xFilterQuery
,
842 const uno::Sequence
< beans::NamedValue
>& aSearchRequest
,
843 sal_Int32 nMustFlags
,
844 sal_Int32 nDontFlags
)
846 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
847 uno::Reference
< container::XEnumeration
> xFilterEnum
=
848 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
850 // the first default filter will be taken,
851 // if there is no filter with flag default the first acceptable filter will be taken
852 if ( xFilterEnum
.is() )
854 while ( xFilterEnum
->hasMoreElements() )
856 uno::Sequence
< beans::PropertyValue
> aProps
;
857 if ( xFilterEnum
->nextElement() >>= aProps
)
859 SequenceAsHashMap
aPropsHM( aProps
);
860 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Flags")),
862 if ( ( ( nFlags
& nMustFlags
) == nMustFlags
) && !( nFlags
& nDontFlags
) )
864 if ( ( nFlags
& SFX_FILTER_DEFAULT
) == SFX_FILTER_DEFAULT
)
866 aFilterProps
= aProps
;
869 else if ( !aFilterProps
.getLength() )
870 aFilterProps
= aProps
;
880 //-------------------------------------------------------------------------
881 sal_Bool
MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence
< sal_Int8
>& aClassID1
, const uno::Sequence
< sal_Int8
>& aClassID2
)
883 if ( aClassID1
.getLength() != aClassID2
.getLength() )
886 for ( sal_Int32 nInd
= 0; nInd
< aClassID1
.getLength(); nInd
++ )
887 if ( aClassID1
[nInd
] != aClassID2
[nInd
] )
893 //-------------------------------------------------------------------------
894 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
895 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
896 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
898 uno::Sequence
< sal_Int8
> aResult( 16 );
899 aResult
[0] = (sal_Int8
)( n1
>> 24 );
900 aResult
[1] = (sal_Int8
)( ( n1
<< 8 ) >> 24 );
901 aResult
[2] = (sal_Int8
)( ( n1
<< 16 ) >> 24 );
902 aResult
[3] = (sal_Int8
)( ( n1
<< 24 ) >> 24 );
903 aResult
[4] = (sal_Int8
)( n2
>> 8 );
904 aResult
[5] = (sal_Int8
)( ( n2
<< 8 ) >> 8 );
905 aResult
[6] = (sal_Int8
)( n3
>> 8 );
906 aResult
[7] = (sal_Int8
)( ( n3
<< 8 ) >> 8 );
919 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */