xref: /AOO42X/main/sd/source/filter/sddetect.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 
27 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
28 #include <com/sun/star/uno/Exception.hpp>
29 #include <com/sun/star/uno/Reference.h>
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/io/XInputStream.hpp>
35 #include <com/sun/star/task/XInteractionHandler.hpp>
36 #include <com/sun/star/ucb/InteractiveAppException.hpp>
37 #include <com/sun/star/ucb/XContent.hpp>
38 #include <com/sun/star/packages/zip/ZipIOException.hpp>
39 
40 #include <vos/mutex.hxx>
41 
42 #include <cppuhelper/implbase2.hxx>
43 #include <cppuhelper/factory.hxx>
44 #include <ucbhelper/simpleinteractionrequest.hxx>
45 
46 #include <comphelper/processfactory.hxx>
47 
48 #include <tools/urlobj.hxx>
49 
50 #include <framework/interaction.hxx>
51 
52 #include <svl/itemset.hxx>
53 #include <svl/eitem.hxx>
54 #include <svl/stritem.hxx>
55 
56 #include <svtools/filter.hxx>
57 #include <svtools/sfxecode.hxx>
58 #include <svtools/ehdl.hxx>
59 #include <svtools/FilterConfigItem.hxx>
60 
61 #include <sot/storinfo.hxx>
62 #include <sot/storage.hxx>
63 
64 #include <unotools/moduleoptions.hxx>
65 
66 #include <sfx2/app.hxx>
67 #include <sfx2/sfxsids.hrc>
68 #include <sfx2/request.hxx>
69 #include <sfx2/docfile.hxx>
70 #include <sfx2/fcontnr.hxx>
71 #include <sfx2/brokenpackageint.hxx>
72 
73 #include "strmname.h"
74 
75 using ::rtl::OUString;
76 
77 using namespace ::com::sun::star::uno;
78 using namespace ::com::sun::star::io;
79 using namespace ::com::sun::star::frame;
80 using namespace ::com::sun::star::embed;
81 using namespace ::com::sun::star::task;
82 using namespace ::com::sun::star::beans;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::ucb;
85 
86 class SdFilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, XServiceInfo >
87 {
88 public:
89     SdFilterDetect( const Reference < XMultiServiceFactory >& xFactory );
90     virtual ~SdFilterDetect();
91 
92     virtual OUString SAL_CALL getImplementationName(  ) throw (RuntimeException);
93     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException);
94     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException);
95 
96     static Sequence< OUString > impl_getStaticSupportedServiceNames();
97     static OUString impl_getStaticImplementationName();
98     static Reference< XInterface > SAL_CALL impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( Exception );
99     virtual OUString SAL_CALL detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException );
100 };
101 
SdFilterDetect(const Reference<XMultiServiceFactory> &)102 SdFilterDetect::SdFilterDetect( const Reference < XMultiServiceFactory >&  )
103 {
104 }
105 
~SdFilterDetect()106 SdFilterDetect::~SdFilterDetect()
107 {
108 }
109 
detect(Sequence<PropertyValue> & lDescriptor)110 OUString SAL_CALL SdFilterDetect::detect( Sequence< PropertyValue >& lDescriptor ) throw( RuntimeException )
111 {
112     Reference< XInputStream > xStream;
113     Reference< XContent > xContent;
114     Reference< XInteractionHandler > xInteraction;
115     String aURL;
116     OUString sTemp;
117     String aTypeName;            // a name describing the type (from MediaDescriptor, usually from flat detection)
118     String aPreselectedFilterName;      // a name describing the filter to use (from MediaDescriptor, usually from UI action)
119 
120     OUString aDocumentTitle; // interesting only if set in this method
121 
122     // opening as template is done when a parameter tells to do so and a template filter can be detected
123     // (otherwise no valid filter would be found) or if the detected filter is a template filter and
124     // there is no parameter that forbids to open as template
125     sal_Bool bOpenAsTemplate = sal_False;
126     sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
127 
128     sal_Bool bRepairPackage = sal_False;
129     sal_Bool bRepairAllowed = sal_False;
130 
131     // now some parameters that can already be in the array, but may be overwritten or new inserted here
132     // remember their indices in the case new values must be added to the array
133     sal_Int32 nPropertyCount = lDescriptor.getLength();
134     sal_Int32 nIndexOfFilterName = -1;
135     sal_Int32 nIndexOfInputStream = -1;
136     sal_Int32 nIndexOfContent = -1;
137     sal_Int32 nIndexOfReadOnlyFlag = -1;
138     sal_Int32 nIndexOfTemplateFlag = -1;
139     sal_Int32 nIndexOfDocumentTitle = -1;
140 
141     for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
142     {
143         // extract properties
144         if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
145         {
146             lDescriptor[nProperty].Value >>= sTemp;
147             aURL = sTemp;
148         }
149         else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
150         {
151             lDescriptor[nProperty].Value >>= sTemp;
152             aURL = sTemp;
153         }
154         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
155         {
156             lDescriptor[nProperty].Value >>= sTemp;
157             aTypeName = sTemp;
158         }
159         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
160         {
161             lDescriptor[nProperty].Value >>= sTemp;
162             aPreselectedFilterName = sTemp;
163 
164             // if the preselected filter name is not correct, it must be erased after detection
165             // remember index of property to get access to it later
166             nIndexOfFilterName = nProperty;
167         }
168         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
169             nIndexOfInputStream = nProperty;
170         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
171             nIndexOfReadOnlyFlag = nProperty;
172         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
173             nIndexOfContent = nProperty;
174         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
175         {
176             lDescriptor[nProperty].Value >>= bOpenAsTemplate;
177             nIndexOfTemplateFlag = nProperty;
178         }
179         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
180             lDescriptor[nProperty].Value >>= xInteraction;
181         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) )
182             lDescriptor[nProperty].Value >>= bRepairPackage;
183         else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
184             nIndexOfDocumentTitle = nProperty;
185     }
186 
187     // can't check the type for external filters, so set the "dont" flag accordingly
188     ::vos::OGuard aGuard( Application::GetSolarMutex() );
189     //SfxFilterFlags nMust = SFX_FILTER_IMPORT, nDont = SFX_FILTER_NOTINSTALLED;
190 
191     SfxApplication* pApp = SFX_APP();
192     SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
193     TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
194     SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
195 
196     bWasReadOnly = pItem && pItem->GetValue();
197 
198     const SfxFilter* pFilter = 0;
199     String aFilterName;
200     String aPrefix = String::CreateFromAscii( "private:factory/" );
201     if( aURL.Match( aPrefix ) == aPrefix.Len() )
202     {
203         if( SvtModuleOptions().IsImpress() )
204         {
205             String aPattern( aPrefix );
206             aPattern += String::CreateFromAscii("simpress");
207             if ( aURL.Match( aPattern ) >= aPattern.Len() )
208                 pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
209         }
210 
211         if( !pFilter && SvtModuleOptions().IsDraw() )
212         {
213             String aPattern( aPrefix );
214             aPattern += String::CreateFromAscii("sdraw");
215             if ( aURL.Match( aPattern ) >= aPattern.Len() )
216                 pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
217         }
218     }
219     else
220     {
221         // ctor of SfxMedium uses owner transition of ItemSet
222         SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, sal_False, NULL, pSet );
223         aMedium.UseInteractionHandler( sal_True );
224         if ( aPreselectedFilterName.Len() )
225             pFilter = SfxFilter::GetFilterByName( aPreselectedFilterName );
226         else if( aTypeName.Len() )
227         {
228             SfxFilterMatcher aMatch;
229             pFilter = aMatch.GetFilter4EA( aTypeName );
230         }
231 
232         if ( aMedium.GetErrorCode() == ERRCODE_NONE )
233         {
234             // remember input stream and content and put them into the descriptor later
235             // should be done here since later the medium can switch to a version
236             xStream = aMedium.GetInputStream();
237             xContent = aMedium.GetContent();
238             bReadOnly = aMedium.IsReadOnly();
239             sal_Bool bIsStorage = aMedium.IsStorage();
240 
241             if (aMedium.GetError() == SVSTREAM_OK)
242             {
243                 if ( bIsStorage )
244                 {
245                     // PowerPoint needs to be detected via StreamName, all other storage based formats are our own and can
246                     // be detected by the ClipboardId, so except for the PPT filter all filters must have a ClipboardId set
247                     Reference< XStorage > xStorage( aMedium.GetStorage( sal_False ) );
248 
249                     //TODO/LATER: move error handling to central place! (maybe even complete own filters)
250                     if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
251                     {
252                         // error during storage creation means _here_ that the medium
253                         // is broken, but we can not handle it in medium since unpossibility
254                         // to create a storage does not _always_ means that the medium is broken
255                         aMedium.SetError( aMedium.GetLastStorageCreationState(), OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
256                         if ( xInteraction.is() )
257                         {
258                             OUString empty;
259                             try
260                             {
261                                 InteractiveAppException xException( empty,
262                                     Reference< XInterface >(),
263                                     InteractionClassification_ERROR,
264                                     aMedium.GetError() );
265 
266                                 Reference< XInteractionRequest > xRequest(
267                                     new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
268                                     ucbhelper::CONTINUATION_APPROVE ) );
269                                 xInteraction->handle( xRequest );
270                             }
271                             catch ( Exception & ) {};
272                         }
273                     }
274                     else
275                     {
276                         if ( pFilter && !pFilter->GetFormat() )
277                             // preselected Filter has no ClipboardId -> doesn't match (see comment above)
278                             pFilter = 0;
279 
280                         // the storage must be checked even if filter is already found, since it is deep type detection
281                         // the storage can be corrupted and it will be detected here
282                         try
283                         {
284                             String sFilterName;
285                             if ( pFilter )
286                                 sFilterName = pFilter->GetName();
287                             aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsOwnTemplateFormat() : sal_False, &sFilterName );
288                         }
289                         catch( WrappedTargetException& aWrap )
290                         {
291                             com::sun::star::packages::zip::ZipIOException aZipException;
292                             if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
293                             {
294                                 if ( xInteraction.is() )
295                                 {
296                                     // the package is broken one
297                                     aDocumentTitle = aMedium.GetURLObject().getName(
298                                         INetURLObject::LAST_SEGMENT,
299                                         true,
300                                         INetURLObject::DECODE_WITH_CHARSET );
301 
302                                     if ( !bRepairPackage )
303                                     {
304                                         // ask the user whether he wants to try to repair
305                                         RequestPackageReparation aRequest( aDocumentTitle );
306                                         xInteraction->handle( aRequest.GetRequest() );
307                                         bRepairAllowed = aRequest.isApproved();
308                                     }
309 
310                                     if ( !bRepairAllowed )
311                                     {
312                                         // repair either not allowed or not successful
313                                         NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
314                                         xInteraction->handle( aNotifyRequest.GetRequest() );
315                                     }
316                                 }
317 
318                                 if ( !bRepairAllowed )
319                                 {
320                                     aTypeName.Erase();
321                                     pFilter = 0;
322                                 }
323                             }
324                         }
325                         catch( RuntimeException& )
326                         {
327                             throw;
328                         }
329                         catch( Exception& )
330                         {
331                             aTypeName.Erase();
332                             pFilter = 0;
333                         }
334 
335                         if ( !pFilter && aTypeName.Len() )
336                         {
337                             //TODO/LATER: using this method impress is always preferred if no flat detecion has been made
338                             // this should been discussed!
339                             if ( SvtModuleOptions().IsImpress() )
340                                 pFilter = SfxFilterMatcher( String::CreateFromAscii("simpress") ).GetFilter4EA( aTypeName );
341                             else if ( SvtModuleOptions().IsDraw() )
342                                 pFilter = SfxFilterMatcher( String::CreateFromAscii("sdraw") ).GetFilter4EA( aTypeName );
343                         }
344                     }
345                 }
346                 else
347                 {
348                     SvStream* pStm = aMedium.GetInStream();
349                     if ( !pStm )
350                     {
351                         pFilter = 0;
352                     }
353                     else
354                     {
355                         SotStorageRef aStorage = new SotStorage ( pStm, sal_False );
356                         if ( !aStorage->GetError() )
357                         {
358                             String aStreamName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) );
359                             if ( aStorage->IsStream( aStreamName ) && SvtModuleOptions().IsImpress() )
360                             {
361                                 String aFileName(aMedium.GetName());
362                                 aFileName.ToUpperAscii();
363 
364                                 if( aFileName.SearchAscii( ".POT" ) == STRING_NOTFOUND )
365                                     pFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97);
366                                 else
367                                     pFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97Template );
368                             }
369                         }
370                         else
371                         {
372                             // Vektorgraphik?
373                             pStm->Seek( STREAM_SEEK_TO_BEGIN );
374 
375                             const String        aFileName( aMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
376                             GraphicDescriptor   aDesc( *pStm, &aFileName );
377                             GraphicFilter*      pGrfFilter = GraphicFilter::GetGraphicFilter();
378                             if( !aDesc.Detect( sal_False ) )
379                             {
380                                 pFilter = 0;
381                                 if( SvtModuleOptions().IsImpress() )
382                                 {
383                                     INetURLObject aCheckURL( aFileName );
384                                     if( aCheckURL.getExtension().equalsIgnoreAsciiCaseAscii( "cgm" ) )
385                                     {
386                                         sal_uInt8 n8;
387                                         pStm->Seek( STREAM_SEEK_TO_BEGIN );
388                                         *pStm >> n8;
389                                         if ( ( n8 & 0xf0 ) == 0 )       // we are supporting binary cgm format only, so
390                                         {                               // this is a small test to exclude cgm text
391                                             const String aName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "CGM - Computer Graphics Metafile" ) );
392                                             SfxFilterMatcher aMatch( String::CreateFromAscii("simpress") );
393                                             pFilter = aMatch.GetFilter4FilterName( aName );
394                                         }
395                                     }
396                                 }
397                             }
398                             else
399                             {
400                                 String aShortName( aDesc.GetImportFormatShortName( aDesc.GetFileFormat() ) );
401                                 const String aName( pGrfFilter->GetImportFormatTypeName( pGrfFilter->GetImportFormatNumberForShortName( aShortName ) ) );
402 
403                                 if ( pFilter && aShortName.EqualsIgnoreCaseAscii( "PCD" ) )    // there is a multiple pcd selection possible
404                                 {
405                                     sal_Int32 nBase = 2;    // default Base0
406                                     String aFilterTypeName( pFilter->GetRealTypeName() );
407                                     if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base4" ) == COMPARE_EQUAL )
408                                         nBase = 1;
409                                     else if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base16" ) == COMPARE_EQUAL )
410                                         nBase = 0;
411                                     String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
412                                     FilterConfigItem aFilterConfigItem( aFilterConfigPath );
413                                     aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
414                                 }
415 
416                                 SfxFilterMatcher aMatch( String::CreateFromAscii("sdraw") );
417                                 pFilter = aMatch.GetFilter4FilterName( aName );
418                             }
419                         }
420                     }
421                 }
422             }
423         }
424     }
425 
426     if ( nIndexOfInputStream == -1 && xStream.is() )
427     {
428         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
429         lDescriptor.realloc( nPropertyCount + 1 );
430         lDescriptor[nPropertyCount].Name = OUString::createFromAscii("InputStream");
431         lDescriptor[nPropertyCount].Value <<= xStream;
432         nPropertyCount++;
433     }
434 
435     if ( nIndexOfContent == -1 && xContent.is() )
436     {
437         // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
438         lDescriptor.realloc( nPropertyCount + 1 );
439         lDescriptor[nPropertyCount].Name = OUString::createFromAscii("UCBContent");
440         lDescriptor[nPropertyCount].Value <<= xContent;
441         nPropertyCount++;
442     }
443 
444     if ( bReadOnly != bWasReadOnly )
445     {
446         if ( nIndexOfReadOnlyFlag == -1 )
447         {
448             lDescriptor.realloc( nPropertyCount + 1 );
449             lDescriptor[nPropertyCount].Name = OUString::createFromAscii("ReadOnly");
450             lDescriptor[nPropertyCount].Value <<= bReadOnly;
451             nPropertyCount++;
452         }
453         else
454             lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
455     }
456 
457     if ( !bRepairPackage && bRepairAllowed )
458     {
459         lDescriptor.realloc( nPropertyCount + 1 );
460         lDescriptor[nPropertyCount].Name = OUString::createFromAscii("RepairPackage");
461         lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
462         nPropertyCount++;
463 
464         bOpenAsTemplate = sal_True;
465 
466         // TODO/LATER: set progress bar that should be used
467     }
468 
469     if ( bOpenAsTemplate )
470     {
471         if ( nIndexOfTemplateFlag == -1 )
472         {
473             lDescriptor.realloc( nPropertyCount + 1 );
474             lDescriptor[nPropertyCount].Name = OUString::createFromAscii("AsTemplate");
475             lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
476             nPropertyCount++;
477         }
478         else
479             lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
480     }
481 
482     if ( aDocumentTitle.getLength() )
483     {
484         // the title was set here
485         if ( nIndexOfDocumentTitle == -1 )
486         {
487             lDescriptor.realloc( nPropertyCount + 1 );
488             lDescriptor[nPropertyCount].Name = OUString::createFromAscii("DocumentTitle");
489             lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
490             nPropertyCount++;
491         }
492         else
493             lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
494     }
495 
496     if ( pFilter )
497         aTypeName = pFilter->GetTypeName();
498     else
499         aTypeName.Erase();
500 
501     return aTypeName;
502 }
503 
504 /* XServiceInfo */
getImplementationName()505 OUString SAL_CALL SdFilterDetect::getImplementationName() throw( RuntimeException )
506 {
507     return impl_getStaticImplementationName();
508 }
509 
510 /* XServiceInfo */
supportsService(const OUString & sServiceName)511 sal_Bool SAL_CALL SdFilterDetect::supportsService( const OUString& sServiceName ) throw( RuntimeException )
512 {
513     Sequence< OUString >  seqServiceNames =   getSupportedServiceNames();
514     const OUString*          pArray          =   seqServiceNames.getConstArray();
515     for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
516     {
517         if ( pArray[nCounter] == sServiceName )
518         {
519             return sal_True ;
520         }
521     }
522     return sal_False ;
523 }
524 
525 /* XServiceInfo */
getSupportedServiceNames()526 Sequence< OUString > SAL_CALL SdFilterDetect::getSupportedServiceNames() throw( RuntimeException )
527 {
528     return impl_getStaticSupportedServiceNames();
529 }
530 
531 /* Helper for XServiceInfo */
impl_getStaticSupportedServiceNames()532 Sequence< OUString > SdFilterDetect::impl_getStaticSupportedServiceNames()
533 {
534     ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
535     Sequence< OUString > seqServiceNames( 1 );
536     seqServiceNames.getArray() [0] = OUString::createFromAscii( "com.sun.star.frame.ExtendedTypeDetection"  );
537     return seqServiceNames ;
538 }
539 
540 /* Helper for XServiceInfo */
impl_getStaticImplementationName()541 OUString SdFilterDetect::impl_getStaticImplementationName()
542 {
543     return OUString::createFromAscii( "com.sun.star.comp.draw.FormatDetector" );
544 }
545 
546 /* Helper for registry */
impl_createInstance(const Reference<XMultiServiceFactory> & xServiceManager)547 Reference< XInterface > SAL_CALL SdFilterDetect::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( Exception )
548 {
549     return Reference< XInterface >( *new SdFilterDetect( xServiceManager ) );
550 }
551 
552 extern "C" {
553 
component_getImplementationEnvironment(const sal_Char ** ppEnvironmentTypeName,uno_Environment **)554     SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
555         const  sal_Char**   ppEnvironmentTypeName,
556         uno_Environment**              )
557     {
558         *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
559     }
560 
component_getFactory(const sal_Char * pImplementationName,void * pServiceManager,void *)561     SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(
562         const sal_Char* pImplementationName,
563         void* pServiceManager,
564         void*  )
565     {
566         // Set default return value for this operation - if it failed.
567         void* pReturn = NULL ;
568 
569         if  (
570             ( pImplementationName   !=  NULL ) &&
571             ( pServiceManager       !=  NULL )
572             )
573         {
574             // Define variables which are used in following macros.
575             Reference< XSingleServiceFactory >   xFactory                                                                                                ;
576             Reference< XMultiServiceFactory >    xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
577 
578             if( SdFilterDetect::impl_getStaticImplementationName().equalsAscii( pImplementationName ) )
579             {
580                 xFactory = ::cppu::createSingleFactory( xServiceManager,
581                     SdFilterDetect::impl_getStaticImplementationName(),
582                     SdFilterDetect::impl_createInstance,
583                     SdFilterDetect::impl_getStaticSupportedServiceNames() );
584             }
585 
586             // Factory is valid - service was found.
587             if ( xFactory.is() )
588             {
589                 xFactory->acquire();
590                 pReturn = xFactory.get();
591             }
592         }
593 
594         // Return with result of this operation.
595         return pReturn ;
596     }
597 } // extern "C"
598