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_unotools.hxx"
26 #ifndef GCC
27 #endif
28 
29 //_________________________________________________________________________________________________________________
30 //	includes
31 //_________________________________________________________________________________________________________________
32 
33 #include <unotools/moduleoptions.hxx>
34 #include <comphelper/sequenceashashmap.hxx>
35 #include <unotools/configmgr.hxx>
36 #include <unotools/configitem.hxx>
37 #include <unotools/processfactory.hxx>
38 #include <osl/diagnose.h>
39 #include <rtl/ustrbuf.hxx>
40 
41 #include <rtl/logfile.hxx>
42 #include <com/sun/star/uno/Any.hxx>
43 #include <com/sun/star/uno/Sequence.hxx>
44 #include <com/sun/star/beans/PropertyValue.hpp>
45 #include <com/sun/star/container/XNameAccess.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/lang/XServiceInfo.hpp>
48 #include <com/sun/star/document/XTypeDetection.hpp>
49 #include <com/sun/star/util/XStringSubstitution.hpp>
50 
51 #include "itemholder1.hxx"
52 
53 //_________________________________________________________________________________________________________________
54 //	namespaces
55 //_________________________________________________________________________________________________________________
56 
57 #ifndef css
58 namespace css = ::com::sun::star;
59 #endif
60 
61 //_________________________________________________________________________________________________________________
62 //	const
63 //_________________________________________________________________________________________________________________
64 
65 /*-************************************************************************************************************//**
66     @descr          These values are used to define necessary keys from our configuration management to support
67                     all functionality of these implementation.
68 					It's a fast way to make changes if some keys change his name or location!
69 
70                     Property handle are necessary to specify right position in return list of configuration
71 					for asked values. We ask it with a list of properties to get his values. The returned list
72                     has the same order like our given name list!
73                     e.g.:
74                             NAMELIST[ PROPERTYHANDLE_xxx ] => VALUELIST[ PROPERTYHANDLE_xxx ]
75 *//*-*************************************************************************************************************/
76 #define ROOTNODE_FACTORIES                  ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Setup/Office/Factories"        ))
77 #define PATHSEPERATOR                       ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"                             ))
78 
79 // Attention: The property "ooSetupFactoryEmptyDocumentURL" is read from configuration but not used! There is
80 //            special code that uses hard coded strings to return them.
81 #define PROPERTYNAME_SHORTNAME              ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryShortName"       ))
82 #define PROPERTYNAME_TEMPLATEFILE           ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryTemplateFile"    ))
83 #define PROPERTYNAME_WINDOWATTRIBUTES       ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes"))
84 #define PROPERTYNAME_EMPTYDOCUMENTURL       ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryEmptyDocumentURL"))
85 #define PROPERTYNAME_DEFAULTFILTER          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDefaultFilter"   ))
86 #define PROPERTYNAME_ICON                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryIcon"            ))
87 
88 #define PROPERTYHANDLE_SHORTNAME            0
89 #define PROPERTYHANDLE_TEMPLATEFILE         1
90 #define PROPERTYHANDLE_WINDOWATTRIBUTES     2
91 #define PROPERTYHANDLE_EMPTYDOCUMENTURL     3
92 #define PROPERTYHANDLE_DEFAULTFILTER        4
93 #define PROPERTYHANDLE_ICON                 5
94 
95 #define PROPERTYCOUNT                       6
96 
97 #define FACTORYNAME_WRITER                  ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument"                ))
98 #define FACTORYNAME_WRITERWEB               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.WebDocument"                 ))
99 #define FACTORYNAME_WRITERGLOBAL            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.GlobalDocument"              ))
100 #define FACTORYNAME_CALC                    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument"        ))
101 #define FACTORYNAME_DRAW                    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocument"          ))
102 #define FACTORYNAME_IMPRESS                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationDocument"))
103 #define FACTORYNAME_MATH                    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.formula.FormulaProperties"        ))
104 #define FACTORYNAME_CHART                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.chart2.ChartDocument"             ))
105 #define FACTORYNAME_DATABASE                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument"       ))
106 #define FACTORYNAME_STARTMODULE             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule"                ))
107 
108 #define FACTORYCOUNT                        10
109 
110 /*-************************************************************************************************************//**
111     @descr  This struct hold information about one factory. We declare a complete array which can hold infos
112             for all well known factories. Values of enum "EFactory" (see header!) are directly used as index!
113             So we can support a fast access on these informations.
114 *//*-*************************************************************************************************************/
115 struct FactoryInfo
116 {
117     public:
118         //---------------------------------------------------------------------------------------------------------
119         // initialize empty struct
120         FactoryInfo()
121         {
122             free();
123             // @@@ should be supplied from outside!
124             xSMgr = ::utl::getProcessServiceFactory();
125         }
126 
127         //---------------------------------------------------------------------------------------------------------
128         // easy way to reset struct member!
129         void free()
130         {
131             bInstalled                  = sal_False         ;
132             sFactory                    = ::rtl::OUString() ;
133             sShortName                  = ::rtl::OUString() ;
134             sTemplateFile               = ::rtl::OUString() ;
135             sWindowAttributes           = ::rtl::OUString() ;
136             sEmptyDocumentURL           = ::rtl::OUString() ;
137             sDefaultFilter              = ::rtl::OUString() ;
138             nIcon                       = 0                 ;
139             bChangedTemplateFile        = sal_False         ;
140             bChangedWindowAttributes    = sal_False         ;
141             bChangedEmptyDocumentURL    = sal_False         ;
142             bChangedDefaultFilter       = sal_False         ;
143             bChangedIcon                = sal_False         ;
144             bDefaultFilterReadonly      = sal_False         ;
145         }
146 
147         //---------------------------------------------------------------------------------------------------------
148         // returns list of properties, which has changed only!
149         // We use given value of sNodeBase to build full qualified pathes ...
150         // Last sign of it must be "/". Because we use it directly, without any additional things!
151         css::uno::Sequence< css::beans::PropertyValue > getChangedProperties( const ::rtl::OUString& sNodeBase )
152         {
153             // a) reserve memory for max. count of changed properties
154             // b) add names and values of changed ones only and count it
155             // c) resize return list by using count
156             css::uno::Sequence< css::beans::PropertyValue > lProperties   ( 4 );
157             sal_Int8                                        nRealyChanged = 0  ;
158 
159             if( bChangedTemplateFile == sal_True )
160             {
161                 lProperties[nRealyChanged].Name = sNodeBase + PROPERTYNAME_TEMPLATEFILE;
162 
163                 if ( sTemplateFile.getLength() > 0 )
164                 {
165                     lProperties[nRealyChanged].Value
166                         <<= getStringSubstitution()
167                             ->reSubstituteVariables( sTemplateFile );
168                 }
169                 else
170                 {
171                     lProperties[nRealyChanged].Value <<= sTemplateFile;
172                 }
173 
174                 ++nRealyChanged;
175             }
176             if( bChangedWindowAttributes == sal_True )
177             {
178                 lProperties[nRealyChanged].Name    = sNodeBase + PROPERTYNAME_WINDOWATTRIBUTES;
179                 lProperties[nRealyChanged].Value <<= sWindowAttributes;
180                 ++nRealyChanged;
181             }
182             if( bChangedEmptyDocumentURL == sal_True )
183             {
184                 lProperties[nRealyChanged].Name    = sNodeBase + PROPERTYNAME_EMPTYDOCUMENTURL;
185                 lProperties[nRealyChanged].Value <<= sEmptyDocumentURL;
186                 ++nRealyChanged;
187             }
188             if( bChangedDefaultFilter == sal_True )
189             {
190                 lProperties[nRealyChanged].Name    = sNodeBase + PROPERTYNAME_DEFAULTFILTER;
191                 lProperties[nRealyChanged].Value <<= sDefaultFilter;
192                 ++nRealyChanged;
193             }
194             if( bChangedIcon == sal_True )
195             {
196                 lProperties[nRealyChanged].Name    = sNodeBase + PROPERTYNAME_ICON;
197                 lProperties[nRealyChanged].Value <<= nIcon;
198                 ++nRealyChanged;
199             }
200 
201             // Don't forget to reset changed flags! Otherwise we save it again and again and ...
202             bChangedTemplateFile        = sal_False         ;
203             bChangedWindowAttributes    = sal_False         ;
204             bChangedEmptyDocumentURL    = sal_False         ;
205             bChangedDefaultFilter       = sal_False         ;
206             bChangedIcon                = sal_False         ;
207 
208             lProperties.realloc( nRealyChanged );
209             return lProperties;
210         }
211 
212         //---------------------------------------------------------------------------------------------------------
213         // We must support setting AND marking of changed values.
214         // That's why we can't make our member public. We must use get/set/init methods
215         // to control access on it!
216         sal_Bool            getInstalled        () const { return bInstalled;         };
217         ::rtl::OUString     getFactory          () const { return sFactory;           };
218         ::rtl::OUString     getShortName        () const { return sShortName;         };
219         ::rtl::OUString     getTemplateFile     () const { return sTemplateFile;      };
220         ::rtl::OUString     getWindowAttributes () const { return sWindowAttributes;  };
221         ::rtl::OUString     getEmptyDocumentURL () const { return sEmptyDocumentURL;  };
222         ::rtl::OUString     getDefaultFilter    () const { return sDefaultFilter;     };
223         sal_Bool            isDefaultFilterReadonly() const { return bDefaultFilterReadonly; }
224         sal_Int32           getIcon             () const { return nIcon;              };
225 
226         //---------------------------------------------------------------------------------------------------------
227         // If you call set-methods - we check for changes of valkues and mark it.
228         // But if you whish to set it without that ... you must initialize it!
229         void initInstalled        ( sal_Bool               bNewInstalled        ) { bInstalled        = bNewInstalled        ; }
230         void initFactory          ( const ::rtl::OUString& sNewFactory          ) { sFactory          = sNewFactory          ; }
231         void initShortName        ( const ::rtl::OUString& sNewShortName        ) { sShortName        = sNewShortName        ; }
232         void initWindowAttributes ( const ::rtl::OUString& sNewWindowAttributes ) { sWindowAttributes = sNewWindowAttributes ; }
233         void initEmptyDocumentURL ( const ::rtl::OUString& sNewEmptyDocumentURL ) { sEmptyDocumentURL = sNewEmptyDocumentURL ; }
234         void initDefaultFilter    ( const ::rtl::OUString& sNewDefaultFilter    ) { sDefaultFilter    = sNewDefaultFilter    ; }
235         void setDefaultFilterReadonly( const sal_Bool bVal){bDefaultFilterReadonly = bVal;}
236         void initIcon             ( sal_Int32              nNewIcon             ) { nIcon             = nNewIcon             ; }
237 
238         //---------------------------------------------------------------------------------------------------------
239         void initTemplateFile( const ::rtl::OUString& sNewTemplateFile )
240         {
241             if ( sNewTemplateFile.getLength() > 0 )
242             {
243                 sTemplateFile
244                     = getStringSubstitution()
245                         ->substituteVariables( sNewTemplateFile, sal_False );
246             }
247             else
248             {
249                 sTemplateFile = sNewTemplateFile;
250             }
251         }
252 
253         //---------------------------------------------------------------------------------------------------------
254         void setInstalled( sal_Bool bNewInstalled )
255         {
256             bInstalled = bNewInstalled;
257         };
258 
259         //---------------------------------------------------------------------------------------------------------
260         void setFactory( const ::rtl::OUString& sNewFactory )
261         {
262             sFactory = sNewFactory;
263         };
264 
265         //---------------------------------------------------------------------------------------------------------
266         void setShortName( const ::rtl::OUString& sNewShortName )
267         {
268             sShortName = sNewShortName;
269         };
270 
271         //---------------------------------------------------------------------------------------------------------
272         void setTemplateFile( const ::rtl::OUString& sNewTemplateFile )
273         {
274             if( sTemplateFile != sNewTemplateFile )
275             {
276                 sTemplateFile        = sNewTemplateFile;
277                 bChangedTemplateFile = sal_True        ;
278             }
279         };
280 
281         //---------------------------------------------------------------------------------------------------------
282         void setWindowAttributes( const ::rtl::OUString& sNewWindowAttributes )
283         {
284             if( sWindowAttributes != sNewWindowAttributes )
285             {
286                 sWindowAttributes        = sNewWindowAttributes;
287                 bChangedWindowAttributes = sal_True            ;
288             }
289         };
290 
291         //---------------------------------------------------------------------------------------------------------
292         void setEmptyDocumentURL( const ::rtl::OUString& sNewEmptyDocumentURL )
293         {
294             if( sEmptyDocumentURL != sNewEmptyDocumentURL )
295             {
296                 sEmptyDocumentURL        = sNewEmptyDocumentURL;
297                 bChangedEmptyDocumentURL = sal_True            ;
298             }
299         };
300 
301         //---------------------------------------------------------------------------------------------------------
302         void setDefaultFilter( const ::rtl::OUString& sNewDefaultFilter )
303         {
304             if( sDefaultFilter != sNewDefaultFilter )
305             {
306                 sDefaultFilter       = sNewDefaultFilter;
307                 bChangedDefaultFilter = sal_True         ;
308             }
309         };
310 
311         //---------------------------------------------------------------------------------------------------------
312         void setIcon( sal_Int32 nNewIcon )
313         {
314             if( nIcon != nNewIcon )
315             {
316                 nIcon = nNewIcon;
317                 bChangedIcon = sal_True;
318             }
319         };
320 
321     private:
322         css::uno::Reference< css::util::XStringSubstitution > getStringSubstitution()
323         {
324             if ( !xSubstVars.is() )
325             {
326                 xSubstVars
327                     = css::uno::Reference< css::util::XStringSubstitution >(
328                         xSMgr->createInstance(
329                             ::rtl::OUString(
330                                 RTL_CONSTASCII_USTRINGPARAM(
331                                     "com.sun.star.util.PathSubstitution" ) ) ),
332                             css::uno::UNO_QUERY );
333                 if ( !xSubstVars.is() )
334                     throw css::uno::RuntimeException(
335                         ::rtl::OUString(
336                             RTL_CONSTASCII_USTRINGPARAM(
337                                 "Cannot instanciate service "
338                                 "com.sun.star.util.PathSubstitution" ) ),
339                         css::uno::Reference< css::uno::XInterface >() );
340             }
341             return xSubstVars;
342         }
343 
344         sal_Bool            bInstalled                      ;
345         ::rtl::OUString     sFactory                        ;
346         ::rtl::OUString     sShortName                      ;
347         ::rtl::OUString     sTemplateFile                   ;
348         ::rtl::OUString     sWindowAttributes               ;
349         ::rtl::OUString     sEmptyDocumentURL               ;
350         ::rtl::OUString     sDefaultFilter                  ;
351         sal_Int32           nIcon                           ;
352 
353         sal_Bool            bChangedTemplateFile        :1  ;
354         sal_Bool            bChangedWindowAttributes    :1  ;
355         sal_Bool            bChangedEmptyDocumentURL    :1  ;
356         sal_Bool            bChangedDefaultFilter       :1  ;
357         sal_Bool            bChangedIcon                :1  ;
358         sal_Bool            bDefaultFilterReadonly      :1  ;
359 
360         css::uno::Reference< css::lang::XMultiServiceFactory > xSMgr;
361         css::uno::Reference< css::util::XStringSubstitution >  xSubstVars;
362 };
363 
364 typedef FactoryInfo   FactoryInfoList[FACTORYCOUNT];
365 
366 /*-************************************************************************************************************//**
367     @short          IMPL data container for wrapper class SvtModulOptions!
368     @descr          These class is used as a static data container of class SvtModuleOptions. The hold it by using
369                     a refcount and make it threadsafe by using an osl mutex. So we don't must do anything for that.
370                     We can implement pure functionality to read/write configuration data only.
371 
372 	@implements		-
373     @base           ConfigItem
374 
375 	@devstatus		ready to use
376     @threadsafe     no
377 *//*-*************************************************************************************************************/
378 class SvtModuleOptions_Impl : public ::utl::ConfigItem
379 {
380     //-------------------------------------------------------------------------------------------------------------
381 	//	public methods
382 	//-------------------------------------------------------------------------------------------------------------
383 	public:
384         //---------------------------------------------------------------------------------------------------------
385 		//	constructor / destructor
386 		//---------------------------------------------------------------------------------------------------------
387          SvtModuleOptions_Impl(SvtModuleOptions* pOutsideClass);
388         ~SvtModuleOptions_Impl();
389 
390 		//---------------------------------------------------------------------------------------------------------
391 		//	overloaded methods of baseclass
392 		//---------------------------------------------------------------------------------------------------------
393         virtual void Notify( const css::uno::Sequence< ::rtl::OUString >& lPropertyNames );
394         virtual void Commit(                                                             );
395 
396 		//---------------------------------------------------------------------------------------------------------
397 		//	public interface
398 		//---------------------------------------------------------------------------------------------------------
399         sal_Bool        IsModuleInstalled         (       SvtModuleOptions::EModule     eModule    ) const;
400 	    ::com::sun::star::uno::Sequence < ::rtl::OUString > GetAllServiceNames();
401         ::rtl::OUString GetFactoryName            (       SvtModuleOptions::EFactory    eFactory   ) const;
402         ::rtl::OUString GetFactoryShortName       (       SvtModuleOptions::EFactory    eFactory   ) const;
403         ::rtl::OUString GetFactoryStandardTemplate(       SvtModuleOptions::EFactory    eFactory   ) const;
404         ::rtl::OUString GetFactoryWindowAttributes(       SvtModuleOptions::EFactory    eFactory   ) const;
405         ::rtl::OUString GetFactoryEmptyDocumentURL(       SvtModuleOptions::EFactory    eFactory   ) const;
406         ::rtl::OUString GetFactoryDefaultFilter   (       SvtModuleOptions::EFactory    eFactory   ) const;
407         sal_Bool        IsDefaultFilterReadonly(          SvtModuleOptions::EFactory eFactory      ) const;
408         sal_Int32       GetFactoryIcon            (       SvtModuleOptions::EFactory    eFactory   ) const;
409         static sal_Bool ClassifyFactoryByName     ( const ::rtl::OUString&              sName      ,
410                                                           SvtModuleOptions::EFactory&   eFactory   );
411         void            SetFactoryStandardTemplate(       SvtModuleOptions::EFactory    eFactory   ,
412                                                     const ::rtl::OUString&              sTemplate  );
413         void            SetFactoryWindowAttributes(       SvtModuleOptions::EFactory    eFactory   ,
414                                                     const ::rtl::OUString&              sAttributes);
415         void            SetFactoryDefaultFilter   (       SvtModuleOptions::EFactory    eFactory   ,
416                                                     const ::rtl::OUString&              sFilter    );
417         void            MakeReadonlyStatesAvailable();
418 
419 	//-------------------------------------------------------------------------------------------------------------
420 	//	private methods
421 	//-------------------------------------------------------------------------------------------------------------
422 	private:
423         static css::uno::Sequence< ::rtl::OUString > impl_ExpandSetNames ( const css::uno::Sequence< ::rtl::OUString >& lSetNames   );
424                void                                  impl_Read           ( const css::uno::Sequence< ::rtl::OUString >& lSetNames   );
425 
426     //-------------------------------------------------------------------------------------------------------------
427     //  private types
428 	//-------------------------------------------------------------------------------------------------------------
429     private:
430 
431 	//-------------------------------------------------------------------------------------------------------------
432 	//	private member
433 	//-------------------------------------------------------------------------------------------------------------
434 	private:
435         FactoryInfoList     m_lFactories;
436         sal_Bool            m_bReadOnlyStatesWellKnown;
437         SvtModuleOptions*   m_pOutsideClass;
438 };
439 
440 //_________________________________________________________________________________________________________________
441 //	definitions
442 //_________________________________________________________________________________________________________________
443 
444 /*-************************************************************************************************************//**
445     @short      default ctor
446     @descr      We open our configuration here and read all necessary values from it.
447                 These values are cached till everyone call Commit(). Then we write changed ones back to cfg.
448 
449     @seealso    baseclass ConfigItem
450     @seealso    method impl_Read()
451 
452     @param      -
453     @return     -
454 
455     @onerror    -
456     @threadsafe no
457 *//*-*************************************************************************************************************/
458 SvtModuleOptions_Impl::SvtModuleOptions_Impl(SvtModuleOptions* pOutsideClass)
459     :   ::utl::ConfigItem( ROOTNODE_FACTORIES )
460     ,   m_bReadOnlyStatesWellKnown( sal_False )
461     ,   m_pOutsideClass( pOutsideClass )
462 {
463     // First initialize list of factory infos! Otherwise we couldnt guarantee right working of these class.
464     for( sal_Int32 nFactory=0; nFactory<FACTORYCOUNT; ++nFactory )
465         m_lFactories[nFactory].free();
466 
467     // Get name list of all existing set node names in configuration to read her properties in impl_Read().
468     // These list is a list of long names of our factories.
469     const css::uno::Sequence< ::rtl::OUString > lFactories = GetNodeNames( ::rtl::OUString() );
470     impl_Read( lFactories );
471 
472     // Enable notification for changes by using configuration directly.
473     // So we can update our internal values immediately.
474     EnableNotification( lFactories );
475 }
476 
477 /*-************************************************************************************************************//**
478     @short      default dtor
479     @descr      If any values of our cache was modified we should write it back to configuration.
480 
481     @attention  Don't forget to call "SetModified()" method of base class ConfigItem if any interface method
482                 of this class modify internal member list m_lFactories! Otherwise Commit() will never be called!!!
483 
484     @seealso    baseclass ConfigItem
485 
486     @param      -
487     @return     -
488 
489     @onerror    -
490     @threadsafe no
491 *//*-*************************************************************************************************************/
492 SvtModuleOptions_Impl::~SvtModuleOptions_Impl()
493 {
494     if( IsModified() == sal_True )
495 	{
496 		Commit();
497 	}
498 }
499 
500 /*-************************************************************************************************************//**
501     @short      called for notify of configmanager
502     @descr      These method is called from the ConfigManager before application ends or from the
503                 PropertyChangeListener if the sub tree broadcasts changes. You must update our
504                 internal values.
505 
506     @attention  We are registered for pure set node names only. So we can use our internal method "impl_Read()" to
507                 update our info list. Because - these method expand given name list to full qualified property list
508                 and use it to read the values. These values are filled into our internal member list m_lFactories
509                 at right position.
510 
511     @seealso    method impl_Read()
512 
513     @param      "lNames" is the list of set node entries which should be updated.
514     @return     -
515 
516     @onerror    -
517     @threadsafe no
518 *//*-*************************************************************************************************************/
519 void SvtModuleOptions_Impl::Notify( const css::uno::Sequence< ::rtl::OUString >& )
520 {
521     OSL_ENSURE( sal_False, "SvtModuleOptions_Impl::Notify()\nNot implemented yet!\n" );
522 }
523 
524 /*-****************************************************************************************************//**
525     @short      write changes to configuration
526     @descr      These method writes the changed values into the sub tree
527                 and should always called in our destructor to guarantee consistency of config data.
528 
529     @attention  We clear complete set in configuration first and write it completly new! So we don't must
530                 distinguish between existing, added or removed elements. Our internal cached values
531                 are the only and right ones.
532 
533     @seealso    baseclass ConfigItem
534 
535     @param      -
536     @return     -
537 
538     @onerror    -
539     @threadsafe no
540 *//*-*****************************************************************************************************/
541 void SvtModuleOptions_Impl::Commit()
542 {
543     // Reserve memory for ALL possible factory properties!
544     // Step over all factories and get her really changed values only.
545     // Build list of these ones and use it for commit.
546     css::uno::Sequence< css::beans::PropertyValue > lCommitProperties( FACTORYCOUNT*PROPERTYCOUNT );
547     FactoryInfo*                                    pInfo            = NULL                        ;
548     sal_Int32                                       nRealCount       = 0                           ;
549     ::rtl::OUString                                 sBasePath                                      ;
550     for( sal_Int32 nFactory=0; nFactory<FACTORYCOUNT; ++nFactory )
551     {
552         pInfo = &(m_lFactories[nFactory]);
553 
554         // These path is used to build full qualified property names ....
555         // See pInfo->getChangedProperties() for further informations
556         sBasePath  = PATHSEPERATOR + pInfo->getFactory() + PATHSEPERATOR;
557 
558         const css::uno::Sequence< css::beans::PropertyValue > lChangedProperties = pInfo->getChangedProperties ( sBasePath );
559 		const css::beans::PropertyValue*					  pChangedProperties = lChangedProperties.getConstArray();
560         sal_Int32											  nPropertyCount     = lChangedProperties.getLength();
561         for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
562         {
563             lCommitProperties[nRealCount] = pChangedProperties[nProperty];
564             ++nRealCount;
565         }
566     }
567     // Resize commit list to real size.
568     // If nothing to do - suppress calling of configuration ...
569     // It could be to expensive :-)
570     if( nRealCount > 0 )
571     {
572         lCommitProperties.realloc( nRealCount );
573         SetSetProperties( ::rtl::OUString(), lCommitProperties );
574     }
575 }
576 
577 /*-****************************************************************************************************//**
578     @short      access method to get internal values
579     @descr      These methods implement easy access to our internal values.
580                 You give us right enum value to specify which module interest you ... we return right information.
581 
582     @attention  Some poeple use any value as enum ... but we support in header specified values only!
583                 We use it directly as index in our internal list. If enum value isn't right - we crash with an
584                 "index out of range"!!! Please use me right - otherwise there is no guarantee.
585 
586     @seealso    -
587 
588     @param      "eModule"  , index in list - specify module
589     @param      "eFactory" , index in list - specify factory
590     @param      "sTemplate", set new standard template for these factory
591     @return     Queried information.
592 
593     @onerror    We return default values. (mostly "not installed"!)
594     @threadsafe no
595 *//*-*****************************************************************************************************/
596 sal_Bool SvtModuleOptions_Impl::IsModuleInstalled( SvtModuleOptions::EModule eModule ) const
597 {
598     sal_Bool bInstalled = sal_False;
599     switch( eModule )
600     {
601         case SvtModuleOptions::E_SWRITER    :   bInstalled = m_lFactories[SvtModuleOptions::E_WRITER].getInstalled();
602                                                 break;
603         case SvtModuleOptions::E_SWEB       :   bInstalled = m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled();
604                                                 break;
605         case SvtModuleOptions::E_SGLOBAL    :   bInstalled = m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled();
606                                                 break;
607         case SvtModuleOptions::E_SCALC      :   bInstalled = m_lFactories[SvtModuleOptions::E_CALC].getInstalled();
608                                                 break;
609         case SvtModuleOptions::E_SDRAW      :   bInstalled = m_lFactories[SvtModuleOptions::E_DRAW].getInstalled();
610                                                 break;
611         case SvtModuleOptions::E_SIMPRESS   :   bInstalled = m_lFactories[SvtModuleOptions::E_IMPRESS].getInstalled();
612                                                 break;
613         case SvtModuleOptions::E_SMATH      :   bInstalled = m_lFactories[SvtModuleOptions::E_MATH].getInstalled();
614                                                 break;
615         case SvtModuleOptions::E_SCHART     :   bInstalled = m_lFactories[SvtModuleOptions::E_CHART].getInstalled();
616                                                 break;
617         case SvtModuleOptions::E_SSTARTMODULE :   bInstalled = m_lFactories[SvtModuleOptions::E_STARTMODULE].getInstalled();
618                                                 break;
619         case SvtModuleOptions::E_SBASIC     :   bInstalled = sal_True; // Couldn't be deselected by setup yet!
620                                                 break;
621 		case SvtModuleOptions::E_SDATABASE  :   bInstalled = m_lFactories[SvtModuleOptions::E_DATABASE].getInstalled();
622                                                 break;
623     }
624 
625     return bInstalled;
626 }
627 
628 ::com::sun::star::uno::Sequence < ::rtl::OUString > SvtModuleOptions_Impl::GetAllServiceNames()
629 {
630     sal_uInt32 nCount=0;
631     if( m_lFactories[SvtModuleOptions::E_WRITER].getInstalled() )
632 		nCount++;
633 	if ( m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled() )
634 		nCount++;
635 	if ( m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled() )
636 		nCount++;
637     if( m_lFactories[SvtModuleOptions::E_SCALC].getInstalled() )
638 		nCount++;
639     if( m_lFactories[SvtModuleOptions::E_SDRAW].getInstalled() )
640 		nCount++;
641     if( m_lFactories[SvtModuleOptions::E_SIMPRESS].getInstalled() )
642 		nCount++;
643     if( m_lFactories[SvtModuleOptions::E_SCHART].getInstalled() )
644 		nCount++;
645     if( m_lFactories[SvtModuleOptions::E_SMATH].getInstalled() )
646 		nCount++;
647     if( m_lFactories[SvtModuleOptions::E_SBASIC].getInstalled() )
648 		nCount++;
649 	if( m_lFactories[SvtModuleOptions::E_SDATABASE].getInstalled() )
650 		nCount++;
651 
652 	css::uno::Sequence < ::rtl::OUString > aRet( nCount );
653 	sal_Int32 n=0;
654     if( m_lFactories[SvtModuleOptions::E_WRITER].getInstalled() )
655 		aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITER].getFactory();
656 	if ( m_lFactories[SvtModuleOptions::E_WRITERWEB].getInstalled() )
657 		aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITERWEB].getFactory();
658 	if ( m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getInstalled() )
659 		aRet[n++] = m_lFactories[SvtModuleOptions::E_WRITERGLOBAL].getFactory();
660     if( m_lFactories[SvtModuleOptions::E_SCALC].getInstalled() )
661 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SCALC].getFactory();
662     if( m_lFactories[SvtModuleOptions::E_SDRAW].getInstalled() )
663 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SDRAW].getFactory();
664     if( m_lFactories[SvtModuleOptions::E_SIMPRESS].getInstalled() )
665 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SIMPRESS].getFactory();
666     if( m_lFactories[SvtModuleOptions::E_SCHART].getInstalled() )
667 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SCHART].getFactory();
668     if( m_lFactories[SvtModuleOptions::E_SMATH].getInstalled() )
669 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SMATH].getFactory();
670     if( m_lFactories[SvtModuleOptions::E_SBASIC].getInstalled() )
671 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SBASIC].getFactory();
672 	if( m_lFactories[SvtModuleOptions::E_SDATABASE].getInstalled() )
673 		aRet[n++] = m_lFactories[SvtModuleOptions::E_SDATABASE].getFactory();
674 
675 	return aRet;
676 }
677 
678 //*****************************************************************************************************************
679 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryName( SvtModuleOptions::EFactory eFactory ) const
680 {
681     ::rtl::OUString sName;
682 
683     if( eFactory>=0 && eFactory<FACTORYCOUNT )
684     {
685         sName = m_lFactories[eFactory].getFactory();
686     }
687 
688     return sName;
689 }
690 
691 //*****************************************************************************************************************
692 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryShortName( SvtModuleOptions::EFactory eFactory ) const
693 {
694     // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet.
695     //            But it's good to plan further possibilities!
696 
697     //return m_lFactories[eFactory].sShortName;
698 
699     ::rtl::OUString sShortName;
700     switch( eFactory )
701     {
702         case SvtModuleOptions::E_WRITER        :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter"));
703                                                   break;
704         case SvtModuleOptions::E_WRITERWEB     :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter/web"));
705                                                   break;
706         case SvtModuleOptions::E_WRITERGLOBAL  :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("swriter/GlobalDocument"));
707                                                   break;
708         case SvtModuleOptions::E_CALC          :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("scalc"));
709                                                   break;
710         case SvtModuleOptions::E_DRAW          :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdraw"));
711                                                   break;
712         case SvtModuleOptions::E_IMPRESS       :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simpress"));
713                                                   break;
714         case SvtModuleOptions::E_MATH          :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("smath"));
715                                                   break;
716         case SvtModuleOptions::E_CHART         :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("schart"));
717                                                   break;
718         case SvtModuleOptions::E_BASIC         :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sbasic"));
719                                                   break;
720 		case SvtModuleOptions::E_DATABASE     :  sShortName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdatabase"));
721                                                   break;
722         default:
723             OSL_ASSERT( "unknown factory" );
724             break;
725     }
726 
727     return sShortName;
728 }
729 
730 //*****************************************************************************************************************
731 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryStandardTemplate( SvtModuleOptions::EFactory eFactory ) const
732 {
733     ::rtl::OUString sFile;
734 
735     if( eFactory>=0 && eFactory<FACTORYCOUNT )
736     {
737         sFile = m_lFactories[eFactory].getTemplateFile();
738     }
739 
740     return sFile;
741 }
742 
743 //*****************************************************************************************************************
744 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryWindowAttributes( SvtModuleOptions::EFactory eFactory ) const
745 {
746     ::rtl::OUString sAttributes;
747 
748     if( eFactory>=0 && eFactory<FACTORYCOUNT )
749     {
750         sAttributes = m_lFactories[eFactory].getWindowAttributes();
751     }
752 
753     return sAttributes;
754 }
755 
756 //*****************************************************************************************************************
757 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryEmptyDocumentURL( SvtModuleOptions::EFactory eFactory ) const
758 {
759     // Attention: Hard configured yet ... because it's not fine to make changes possible by xml file yet.
760     //            But it's good to plan further possibilities!
761 
762     //return m_lFactories[eFactory].getEmptyDocumentURL();
763 
764     ::rtl::OUString sURL;
765     switch( eFactory )
766     {
767         case SvtModuleOptions::E_WRITER        :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter"));
768                                                   break;
769         case SvtModuleOptions::E_WRITERWEB     :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter/web"));
770                                                   break;
771         case SvtModuleOptions::E_WRITERGLOBAL  :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/swriter/GlobalDocument"));
772                                                   break;
773         case SvtModuleOptions::E_CALC          :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/scalc"));
774                                                   break;
775         case SvtModuleOptions::E_DRAW          :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sdraw"));
776                                                   break;
777         case SvtModuleOptions::E_IMPRESS       :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/simpress?slot=6686"));
778                                                   break;
779         case SvtModuleOptions::E_MATH          :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/smath"));
780                                                   break;
781         case SvtModuleOptions::E_CHART         :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/schart"));
782                                                   break;
783         case SvtModuleOptions::E_BASIC         :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sbasic"));
784                                                   break;
785 		case SvtModuleOptions::E_DATABASE     :  sURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sdatabase?Interactive"));
786                                                   break;
787         default:
788             OSL_ASSERT( "unknown factory" );
789             break;
790     }
791     return sURL;
792 }
793 
794 //*****************************************************************************************************************
795 ::rtl::OUString SvtModuleOptions_Impl::GetFactoryDefaultFilter( SvtModuleOptions::EFactory eFactory ) const
796 {
797     ::rtl::OUString sDefaultFilter;
798 
799     if( eFactory>=0 && eFactory<FACTORYCOUNT )
800     {
801         sDefaultFilter = m_lFactories[eFactory].getDefaultFilter();
802     }
803     return sDefaultFilter;
804 }
805 //*****************************************************************************************************************
806 sal_Bool SvtModuleOptions_Impl::IsDefaultFilterReadonly( SvtModuleOptions::EFactory eFactory   ) const
807 {
808     sal_Bool bRet = sal_False;
809     if( eFactory>=0 && eFactory<FACTORYCOUNT )
810     {
811         bRet = m_lFactories[eFactory].isDefaultFilterReadonly();
812     }
813     return bRet;
814 }
815 
816 //*****************************************************************************************************************
817 sal_Int32 SvtModuleOptions_Impl::GetFactoryIcon( SvtModuleOptions::EFactory eFactory ) const
818 {
819     sal_Int32 nIcon = 0;
820 
821     if( eFactory>=0 && eFactory<FACTORYCOUNT )
822     {
823         nIcon = m_lFactories[eFactory].getIcon();
824     }
825 
826     return nIcon;
827 }
828 
829 //*****************************************************************************************************************
830 void SvtModuleOptions_Impl::SetFactoryStandardTemplate(       SvtModuleOptions::EFactory eFactory   ,
831                                                         const ::rtl::OUString&           sTemplate  )
832 {
833     if( eFactory>=0 && eFactory<FACTORYCOUNT )
834     {
835         m_lFactories[eFactory].setTemplateFile( sTemplate );
836         SetModified();
837     }
838 }
839 
840 //*****************************************************************************************************************
841 void SvtModuleOptions_Impl::SetFactoryWindowAttributes(       SvtModuleOptions::EFactory eFactory   ,
842                                                         const ::rtl::OUString&           sAttributes)
843 {
844     if( eFactory>=0 && eFactory<FACTORYCOUNT )
845     {
846         m_lFactories[eFactory].setWindowAttributes( sAttributes );
847         SetModified();
848     }
849 }
850 
851 //*****************************************************************************************************************
852 void SvtModuleOptions_Impl::SetFactoryDefaultFilter(       SvtModuleOptions::EFactory eFactory,
853                                                      const ::rtl::OUString&           sFilter )
854 {
855     if( eFactory>=0 && eFactory<FACTORYCOUNT )
856     {
857         m_lFactories[eFactory].setDefaultFilter( sFilter );
858         SetModified();
859     }
860 }
861 
862 /*-************************************************************************************************************//**
863     @short      return list of key names of ouer configuration management which represent our module tree
864     @descr      You give use a list of current existing set node names .. and we expand it for all
865                 well known properties which are necessary for this implementation.
866                 These full expanded list should be used to get values of this properties.
867 
868     @seealso    ctor
869 
870     @param      -
871     @return     List of all relative addressed properties of given set entry names.
872 
873     @onerror    List will be empty.
874     @threadsafe no
875 *//*-*************************************************************************************************************/
876 css::uno::Sequence< ::rtl::OUString > SvtModuleOptions_Impl::impl_ExpandSetNames( const css::uno::Sequence< ::rtl::OUString >& lSetNames )
877 {
878     sal_Int32                             nCount     = lSetNames.getLength() ;
879     css::uno::Sequence< ::rtl::OUString > lPropNames ( nCount*PROPERTYCOUNT );
880 	::rtl::OUString*					  pPropNames = lPropNames.getArray() ;
881     sal_Int32                             nPropStart = 0                     ;
882 
883     for( sal_Int32 nName=0; nName<nCount; ++nName )
884     {
885         pPropNames[nPropStart+PROPERTYHANDLE_SHORTNAME       ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_SHORTNAME       ;
886         pPropNames[nPropStart+PROPERTYHANDLE_TEMPLATEFILE    ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_TEMPLATEFILE    ;
887         pPropNames[nPropStart+PROPERTYHANDLE_WINDOWATTRIBUTES] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_WINDOWATTRIBUTES;
888         pPropNames[nPropStart+PROPERTYHANDLE_EMPTYDOCUMENTURL] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_EMPTYDOCUMENTURL;
889         pPropNames[nPropStart+PROPERTYHANDLE_DEFAULTFILTER   ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_DEFAULTFILTER   ;
890         pPropNames[nPropStart+PROPERTYHANDLE_ICON            ] = lSetNames[nName] + PATHSEPERATOR + PROPERTYNAME_ICON            ;
891         nPropStart += PROPERTYCOUNT;
892     }
893 
894     return lPropNames;
895 }
896 
897 /*-************************************************************************************************************//**
898     @short      helper to classify given factory by name
899     @descr      Every factory has his own long and short name. So we can match right enum value for internal using.
900 
901     @attention  We change in/out parameter "eFactory" in every case! But you should use it only, if return value is sal_True!
902                 Algorithm:  Set out-parameter to propably value ... and check the longname.
903                             If it match with these factory - break operation and return true AND right set parameter.
904                             Otherwise try next one and so on. If no factory was found return false. Out parameter eFactory
905                             is set to last tried value but shouldn't be used! Because our return value is false!
906 
907     @seealso    -
908 
909     @param      "sLongName" , long name of factory, which should be classified
910     @return     "eFactory"  , right enum value, which match given long name
911                 and true for successfully classification, false otherwise
912 
913     @onerror    We return false.
914     @threadsafe no
915 *//*-*************************************************************************************************************/
916 sal_Bool SvtModuleOptions_Impl::ClassifyFactoryByName( const ::rtl::OUString& sName, SvtModuleOptions::EFactory& eFactory )
917 {
918     sal_Bool bState;
919 
920     eFactory = SvtModuleOptions::E_WRITER     ;
921     bState   = ( sName == FACTORYNAME_WRITER );
922 
923     if( bState == sal_False )
924     {
925         eFactory = SvtModuleOptions::E_WRITERWEB     ;
926         bState   = ( sName == FACTORYNAME_WRITERWEB );
927     }
928     // no else!
929     if( bState == sal_False )
930     {
931         eFactory = SvtModuleOptions::E_WRITERGLOBAL     ;
932         bState   = ( sName == FACTORYNAME_WRITERGLOBAL );
933     }
934     // no else!
935     if( bState == sal_False )
936     {
937         eFactory = SvtModuleOptions::E_CALC     ;
938         bState   = ( sName == FACTORYNAME_CALC );
939     }
940     // no else!
941     if( bState == sal_False )
942     {
943         eFactory = SvtModuleOptions::E_DRAW     ;
944         bState   = ( sName == FACTORYNAME_DRAW );
945     }
946     // no else!
947     if( bState == sal_False )
948     {
949         eFactory = SvtModuleOptions::E_IMPRESS     ;
950         bState   = ( sName == FACTORYNAME_IMPRESS );
951     }
952     // no else!
953     if( bState == sal_False )
954     {
955         eFactory = SvtModuleOptions::E_MATH     ;
956         bState   = ( sName == FACTORYNAME_MATH );
957     }
958     // no else!
959     if( bState == sal_False )
960     {
961         eFactory = SvtModuleOptions::E_CHART     ;
962         bState   = ( sName == FACTORYNAME_CHART );
963     }
964 	// no else!
965     if( bState == sal_False )
966     {
967         eFactory = SvtModuleOptions::E_DATABASE     ;
968         bState   = ( sName == FACTORYNAME_DATABASE );
969     }
970     // no else!
971     if( bState == sal_False )
972     {
973         eFactory = SvtModuleOptions::E_STARTMODULE    ;
974         bState   = ( sName == FACTORYNAME_STARTMODULE);
975     }
976 
977     return bState;
978 }
979 
980 /*-************************************************************************************************************//**
981     @short      read factory configuration
982     @descr      Give us a list of pure factory names (long names!) which can be used as
983                 direct set node names ... and we read her property values and fill internal list.
984                 These method can be used by initial reading at ctor and later updating by "Notify()".
985 
986     @seealso    ctor
987     @seealso    method Notify()
988 
989     @param      "lFactories" is the list of set node entries which should be readed.
990     @return     -
991 
992     @onerror    We do nothing.
993     @threadsafe no
994 *//*-*************************************************************************************************************/
995 void SvtModuleOptions_Impl::impl_Read( const css::uno::Sequence< ::rtl::OUString >& lFactories )
996 {
997     // Expand every set node name in lFactories to full qualified pathes to his properties
998     // and get right values from configuration.
999     const css::uno::Sequence< ::rtl::OUString > lProperties = impl_ExpandSetNames( lFactories  );
1000     const css::uno::Sequence< css::uno::Any >   lValues     = GetProperties( lProperties );
1001 
1002 	// Safe impossible cases.
1003 	// We need values from ALL configuration keys.
1004 	// Follow assignment use order of values in relation to our list of key names!
1005     OSL_ENSURE( !(lProperties.getLength()!=lValues.getLength()), "SvtModuleOptions_Impl::impl_Read()\nI miss some values of configuration keys!\n" );
1006 
1007     // Algorithm:   We step over all given factory names and classify it. These enum value can be used as direct index
1008     //              in our member list m_lFactories! VAriable nPropertyStart marks start position of every factory
1009     //              and her properties in expanded property/value list. The defines PROPERTHANDLE_xxx are used as offset values
1010     //              added to nPropertyStart. So we can address every property relative in these lists.
1011     //              If we found any valid values ... we reset all existing informations for corresponding m_lFactories-entry and
1012     //              use a pointer to these struct in memory directly to set new values.
1013     //              But we set it only, if bInstalled is true. Otherwise all other values of a factory can be undeclared .. They
1014     //              shouldn't be used then.
1015     // Attention:   If a propertyset of a factory will be ignored we must step to next start position of next factory infos!
1016     //              see "nPropertyStart += PROPERTYCOUNT" ...
1017 
1018     sal_Int32                   nPropertyStart  = 0                     ;
1019     sal_Int32                   nNodeCount      = lFactories.getLength();
1020     FactoryInfo*                pInfo           = NULL                  ;
1021     SvtModuleOptions::EFactory  eFactory                                ;
1022 
1023     for( sal_Int32 nSetNode=0; nSetNode<nNodeCount; ++nSetNode )
1024     {
1025         const ::rtl::OUString& sFactoryName = lFactories[nSetNode];
1026         if( ClassifyFactoryByName( sFactoryName, eFactory ) == sal_True )
1027         {
1028 			::rtl::OUString sTemp;
1029 			sal_Int32       nTemp = 0;
1030 
1031             pInfo = &(m_lFactories[eFactory]);
1032             pInfo->free();
1033 
1034             pInfo->initInstalled( sal_True     );
1035             pInfo->initFactory  ( sFactoryName );
1036 
1037             if (lValues[nPropertyStart+PROPERTYHANDLE_SHORTNAME] >>= sTemp)
1038 				pInfo->initShortName( sTemp );
1039             if (lValues[nPropertyStart+PROPERTYHANDLE_TEMPLATEFILE] >>= sTemp)
1040 				pInfo->initTemplateFile( sTemp );
1041             if (lValues[nPropertyStart+PROPERTYHANDLE_WINDOWATTRIBUTES] >>= sTemp)
1042 				pInfo->initWindowAttributes( sTemp );
1043             if (lValues[nPropertyStart+PROPERTYHANDLE_EMPTYDOCUMENTURL] >>= sTemp)
1044 				pInfo->initEmptyDocumentURL( sTemp );
1045             if (lValues[nPropertyStart+PROPERTYHANDLE_DEFAULTFILTER   ] >>= sTemp)
1046 	            pInfo->initDefaultFilter( sTemp );
1047             if (lValues[nPropertyStart+PROPERTYHANDLE_ICON] >>= nTemp)
1048 				pInfo->initIcon( nTemp );
1049         }
1050         nPropertyStart += PROPERTYCOUNT;
1051     }
1052 }
1053 
1054 //*****************************************************************************************************************
1055 void SvtModuleOptions_Impl::MakeReadonlyStatesAvailable()
1056 {
1057     if (m_bReadOnlyStatesWellKnown)
1058         return;
1059 
1060     css::uno::Sequence< ::rtl::OUString > lFactories = GetNodeNames(::rtl::OUString());
1061     sal_Int32 c = lFactories.getLength();
1062     sal_Int32 i = 0;
1063     for (i=0; i<c; ++i)
1064     {
1065         ::rtl::OUStringBuffer sPath(256);
1066         sPath.append(lFactories[i]             );
1067         sPath.append(PATHSEPERATOR             );
1068         sPath.append(PROPERTYNAME_DEFAULTFILTER);
1069 
1070         lFactories[i] = sPath.makeStringAndClear();
1071     }
1072 
1073     css::uno::Sequence< sal_Bool > lReadonlyStates = GetReadOnlyStates(lFactories);
1074     for (i=0; i<c; ++i)
1075     {
1076         ::rtl::OUString&            rFactoryName = lFactories[i];
1077         SvtModuleOptions::EFactory  eFactory                    ;
1078 
1079         if (!ClassifyFactoryByName(rFactoryName, eFactory))
1080             continue;
1081 
1082         FactoryInfo& rInfo = m_lFactories[eFactory];
1083         rInfo.setDefaultFilterReadonly(lReadonlyStates[i]);
1084     }
1085 
1086     m_bReadOnlyStatesWellKnown = sal_True;
1087 }
1088 
1089 //*****************************************************************************************************************
1090 //	initialize static member
1091 //	DON'T DO IT IN YOUR HEADER!
1092 //	see definition for further informations
1093 //*****************************************************************************************************************
1094 SvtModuleOptions_Impl*  SvtModuleOptions::m_pDataContainer  = NULL  ;
1095 sal_Int32               SvtModuleOptions::m_nRefCount       = 0     ;
1096 
1097 /*-************************************************************************************************************//**
1098     @short      standard constructor and destructor
1099     @descr      This will initialize an instance with default values. We initialize/deinitialize our static data
1100                 container and create a static mutex, which is used for threadsafe code in further time of this object.
1101 
1102     @seealso    method impl_GetOwnStaticMutex()
1103 
1104     @param      -
1105     @return     -
1106 
1107     @onerror    -
1108     @threadsafe yes
1109 *//*-*************************************************************************************************************/
1110 SvtModuleOptions::SvtModuleOptions()
1111 {
1112     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1113 	++m_nRefCount;
1114     if( m_nRefCount == 1 )
1115 	{
1116         RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtModuleOptions_Impl::ctor()");
1117         m_pDataContainer = new SvtModuleOptions_Impl(this);
1118 
1119         ItemHolder1::holdConfigItem(E_MODULEOPTIONS);
1120 	}
1121 }
1122 
1123 //*****************************************************************************************************************
1124 SvtModuleOptions::~SvtModuleOptions()
1125 {
1126     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1127 	--m_nRefCount;
1128     if( m_nRefCount == 0 )
1129 	{
1130 		delete m_pDataContainer;
1131 		m_pDataContainer = NULL;
1132 	}
1133 }
1134 
1135 /*-************************************************************************************************************//**
1136     @short      access to configuration data
1137     @descr      This methods allow read/write access to configuration values.
1138                 They are threadsafe. All calls are forwarded to impl-data-container. See there for further informations!
1139 
1140     @seealso    method impl_GetOwnStaticMutex()
1141 
1142     @param      -
1143     @return     -
1144 
1145     @onerror    -
1146     @threadsafe yes
1147 *//*-*************************************************************************************************************/
1148 sal_Bool SvtModuleOptions::IsModuleInstalled( EModule eModule ) const
1149 {
1150     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1151     return m_pDataContainer->IsModuleInstalled( eModule );
1152 }
1153 
1154 //*****************************************************************************************************************
1155 ::rtl::OUString SvtModuleOptions::GetFactoryName( EFactory eFactory ) const
1156 {
1157     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1158     return m_pDataContainer->GetFactoryName( eFactory );
1159 }
1160 
1161 //*****************************************************************************************************************
1162 ::rtl::OUString SvtModuleOptions::GetFactoryShortName( EFactory eFactory ) const
1163 {
1164     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1165     return m_pDataContainer->GetFactoryShortName( eFactory );
1166 }
1167 
1168 //*****************************************************************************************************************
1169 ::rtl::OUString SvtModuleOptions::GetFactoryStandardTemplate( EFactory eFactory ) const
1170 {
1171     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1172     return m_pDataContainer->GetFactoryStandardTemplate( eFactory );
1173 }
1174 
1175 //*****************************************************************************************************************
1176 ::rtl::OUString SvtModuleOptions::GetFactoryWindowAttributes( EFactory eFactory ) const
1177 {
1178     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1179     return m_pDataContainer->GetFactoryWindowAttributes( eFactory );
1180 }
1181 
1182 //*****************************************************************************************************************
1183 ::rtl::OUString SvtModuleOptions::GetFactoryEmptyDocumentURL( EFactory eFactory ) const
1184 {
1185     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1186     return m_pDataContainer->GetFactoryEmptyDocumentURL( eFactory );
1187 }
1188 
1189 //*****************************************************************************************************************
1190 ::rtl::OUString SvtModuleOptions::GetFactoryDefaultFilter( EFactory eFactory ) const
1191 {
1192     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1193     return m_pDataContainer->GetFactoryDefaultFilter( eFactory );
1194 }
1195 //*****************************************************************************************************************
1196 sal_Bool SvtModuleOptions::IsDefaultFilterReadonly( EFactory eFactory   ) const
1197 {
1198     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1199     m_pDataContainer->MakeReadonlyStatesAvailable();
1200     return m_pDataContainer->IsDefaultFilterReadonly( eFactory );
1201 }
1202 //*****************************************************************************************************************
1203 sal_Int32 SvtModuleOptions::GetFactoryIcon( EFactory eFactory ) const
1204 {
1205     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1206     return m_pDataContainer->GetFactoryIcon( eFactory );
1207 }
1208 
1209 //*****************************************************************************************************************
1210 sal_Bool SvtModuleOptions::ClassifyFactoryByName( const ::rtl::OUString& sName    ,
1211                                                         EFactory&        eFactory )
1212 {
1213     // We don't need any mutex here ... because we don't use any member here!
1214     return SvtModuleOptions_Impl::ClassifyFactoryByName( sName, eFactory );
1215 }
1216 
1217 //*****************************************************************************************************************
1218 void SvtModuleOptions::SetFactoryStandardTemplate(       EFactory         eFactory   ,
1219                                                    const ::rtl::OUString& sTemplate  )
1220 {
1221     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1222     m_pDataContainer->SetFactoryStandardTemplate( eFactory, sTemplate );
1223 }
1224 
1225 //*****************************************************************************************************************
1226 void SvtModuleOptions::SetFactoryWindowAttributes(       EFactory         eFactory   ,
1227                                                    const ::rtl::OUString& sAttributes)
1228 {
1229     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1230     m_pDataContainer->SetFactoryWindowAttributes( eFactory, sAttributes );
1231 }
1232 
1233 //*****************************************************************************************************************
1234 void SvtModuleOptions::SetFactoryDefaultFilter(       EFactory         eFactory,
1235                                                 const ::rtl::OUString& sFilter )
1236 {
1237     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1238     m_pDataContainer->SetFactoryDefaultFilter( eFactory, sFilter );
1239 }
1240 
1241 //*****************************************************************************************************************
1242 sal_Bool SvtModuleOptions::IsMath() const
1243 {
1244     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1245     return m_pDataContainer->IsModuleInstalled( E_SMATH );
1246 }
1247 
1248 //*****************************************************************************************************************
1249 sal_Bool SvtModuleOptions::IsChart() const
1250 {
1251     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1252     return m_pDataContainer->IsModuleInstalled( E_SCHART );
1253 }
1254 
1255 //*****************************************************************************************************************
1256 sal_Bool SvtModuleOptions::IsCalc() const
1257 {
1258     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1259     return m_pDataContainer->IsModuleInstalled( E_SCALC );
1260 }
1261 
1262 //*****************************************************************************************************************
1263 sal_Bool SvtModuleOptions::IsDraw() const
1264 {
1265     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1266     return m_pDataContainer->IsModuleInstalled( E_SDRAW );
1267 }
1268 
1269 //*****************************************************************************************************************
1270 sal_Bool SvtModuleOptions::IsWriter() const
1271 {
1272     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1273     return m_pDataContainer->IsModuleInstalled( E_SWRITER );
1274 }
1275 
1276 //*****************************************************************************************************************
1277 sal_Bool SvtModuleOptions::IsImpress() const
1278 {
1279     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1280     return m_pDataContainer->IsModuleInstalled( E_SIMPRESS );
1281 }
1282 
1283 //*****************************************************************************************************************
1284 sal_Bool SvtModuleOptions::IsBasicIDE() const
1285 {
1286     return sal_True;
1287 }
1288 //*****************************************************************************************************************
1289 sal_Bool SvtModuleOptions::IsDataBase() const
1290 {
1291     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1292     return m_pDataContainer->IsModuleInstalled( E_SDATABASE );
1293 }
1294 //*****************************************************************************************************************
1295 sal_uInt32 SvtModuleOptions::GetFeatures() const
1296 {
1297     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1298 
1299     sal_uInt32 nFeature = 0;
1300 
1301     if( m_pDataContainer->IsModuleInstalled( E_SWRITER ) == sal_True )
1302         nFeature |= FEATUREFLAG_WRITER;
1303     if( m_pDataContainer->IsModuleInstalled( E_SCALC ) == sal_True )
1304         nFeature |= FEATUREFLAG_CALC;
1305     if( m_pDataContainer->IsModuleInstalled( E_SDRAW ) == sal_True )
1306         nFeature |= FEATUREFLAG_DRAW;
1307     if( m_pDataContainer->IsModuleInstalled( E_SIMPRESS ) == sal_True )
1308         nFeature |= FEATUREFLAG_IMPRESS;
1309     if( m_pDataContainer->IsModuleInstalled( E_SCHART ) == sal_True )
1310         nFeature |= FEATUREFLAG_CHART;
1311     if( m_pDataContainer->IsModuleInstalled( E_SMATH ) == sal_True )
1312         nFeature |= FEATUREFLAG_MATH;
1313     if( m_pDataContainer->IsModuleInstalled( E_SBASIC ) == sal_True )
1314         nFeature |= FEATUREFLAG_BASICIDE;
1315 	if( m_pDataContainer->IsModuleInstalled( E_SDATABASE ) == sal_True )
1316         nFeature |= FEATUREFLAG_INSIGHT;
1317 
1318     return nFeature;
1319 }
1320 
1321 /*-****************************************************************************************************//**
1322     @short      return a reference to a static mutex
1323     @descr      These class is threadsafe.
1324                 We create a static mutex only for one time and use it to protect our refcount and container
1325                 member!
1326 
1327     @seealso    -
1328 
1329     @param      -
1330     @return     A reference to a static mutex member.
1331 
1332     @onerror    -
1333     @threadsafe yes
1334 *//*-*****************************************************************************************************/
1335 ::osl::Mutex& SvtModuleOptions::impl_GetOwnStaticMutex()
1336 {
1337 	// Initialize static mutex only for one time!
1338     static ::osl::Mutex* pMutex = NULL;
1339 	// If these method first called (Mutex not already exist!) ...
1340     if( pMutex == NULL )
1341     {
1342 		// ... we must create a new one. Protect follow code with the global mutex -
1343 		// It must be - we create a static variable!
1344         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1345 		// We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
1346         if( pMutex == NULL )
1347         {
1348 			// Create the new mutex and set it for return on static variable.
1349             static ::osl::Mutex aMutex;
1350             pMutex = &aMutex;
1351         }
1352     }
1353 	// Return new created or already existing mutex object.
1354     return *pMutex;
1355 }
1356 
1357 ::rtl::OUString SvtModuleOptions::GetModuleName( EModule eModule ) const
1358 {
1359     switch( eModule )
1360     {
1361         case SvtModuleOptions::E_SWRITER    :   { return ::rtl::OUString::createFromAscii("Writer"); }
1362         case SvtModuleOptions::E_SWEB       :   { return ::rtl::OUString::createFromAscii("Web"); }
1363         case SvtModuleOptions::E_SGLOBAL    :   { return ::rtl::OUString::createFromAscii("Global"); }
1364         case SvtModuleOptions::E_SCALC      :   { return ::rtl::OUString::createFromAscii("Calc"); }
1365         case SvtModuleOptions::E_SDRAW      :   { return ::rtl::OUString::createFromAscii("Draw"); }
1366         case SvtModuleOptions::E_SIMPRESS   :   { return ::rtl::OUString::createFromAscii("Impress"); }
1367         case SvtModuleOptions::E_SMATH      :   { return ::rtl::OUString::createFromAscii("Math"); }
1368         case SvtModuleOptions::E_SCHART     :   { return ::rtl::OUString::createFromAscii("Chart"); }
1369         case SvtModuleOptions::E_SBASIC     :   { return ::rtl::OUString::createFromAscii("Basic"); }
1370 		case SvtModuleOptions::E_SDATABASE  :   { return ::rtl::OUString::createFromAscii("Database"); }
1371         default:
1372             OSL_ASSERT( "unknown module" );
1373             break;
1374     }
1375 
1376     return ::rtl::OUString();
1377 }
1378 
1379 ::rtl::OUString SvtModuleOptions::GetModuleName( EFactory eFactory ) const
1380 {
1381     switch( eFactory )
1382     {
1383         case SvtModuleOptions::E_WRITER         :   { return ::rtl::OUString::createFromAscii("Writer"); }
1384         case SvtModuleOptions::E_WRITERWEB      :   { return ::rtl::OUString::createFromAscii("Writer"); }
1385         case SvtModuleOptions::E_WRITERGLOBAL   :   { return ::rtl::OUString::createFromAscii("Writer"); }
1386         case SvtModuleOptions::E_CALC           :   { return ::rtl::OUString::createFromAscii("Calc"); }
1387         case SvtModuleOptions::E_DRAW           :   { return ::rtl::OUString::createFromAscii("Draw"); }
1388         case SvtModuleOptions::E_IMPRESS        :   { return ::rtl::OUString::createFromAscii("Impress"); }
1389         case SvtModuleOptions::E_MATH           :   { return ::rtl::OUString::createFromAscii("Math"); }
1390         case SvtModuleOptions::E_CHART          :   { return ::rtl::OUString::createFromAscii("Chart"); }
1391         case SvtModuleOptions::E_BASIC          :   { return ::rtl::OUString::createFromAscii("Basic"); }
1392 		case SvtModuleOptions::E_DATABASE		:   { return ::rtl::OUString::createFromAscii("Database"); }
1393         default:
1394             OSL_ASSERT( "unknown factory" );
1395             break;
1396     }
1397 
1398     return ::rtl::OUString();
1399 }
1400 
1401 /*-----------------------------------------------
1402     07.03.2004 15:03
1403 -----------------------------------------------*/
1404 SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByShortName(const ::rtl::OUString& sName)
1405 {
1406     if (sName.equalsAscii("swriter"))
1407         return E_WRITER;
1408     if (sName.equalsIgnoreAsciiCaseAscii("swriter/Web")) // sometimes they are registerd for swriter/web :-(
1409         return E_WRITERWEB;
1410     if (sName.equalsIgnoreAsciiCaseAscii("swriter/GlobalDocument")) // sometimes they are registerd for swriter/globaldocument :-(
1411         return E_WRITERGLOBAL;
1412     if (sName.equalsAscii("scalc"))
1413         return E_CALC;
1414     if (sName.equalsAscii("sdraw"))
1415         return E_DRAW;
1416     if (sName.equalsAscii("simpress"))
1417         return E_IMPRESS;
1418     if (sName.equalsAscii("schart"))
1419         return E_CHART;
1420     if (sName.equalsAscii("smath"))
1421         return E_MATH;
1422     if (sName.equalsAscii("sbasic"))
1423         return E_BASIC;
1424     if (sName.equalsAscii("sdatabase"))
1425         return E_DATABASE;
1426 
1427     return E_UNKNOWN_FACTORY;
1428 }
1429 
1430 /*-----------------------------------------------
1431     31.07.2003 10:41
1432 -----------------------------------------------*/
1433 SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByServiceName(const ::rtl::OUString& sName)
1434 {
1435     if (sName.equals(FACTORYNAME_WRITERGLOBAL))
1436         return E_WRITERGLOBAL;
1437     if (sName.equals(FACTORYNAME_WRITERWEB))
1438         return E_WRITERWEB;
1439     if (sName.equals(FACTORYNAME_WRITER))
1440         return E_WRITER;
1441     if (sName.equals(FACTORYNAME_CALC))
1442         return E_CALC;
1443     if (sName.equals(FACTORYNAME_DRAW))
1444         return E_DRAW;
1445     if (sName.equals(FACTORYNAME_IMPRESS))
1446         return E_IMPRESS;
1447     if (sName.equals(FACTORYNAME_MATH))
1448         return E_MATH;
1449     if (sName.equals(FACTORYNAME_CHART))
1450         return E_CHART;
1451 	if (sName.equals(FACTORYNAME_DATABASE))
1452         return E_DATABASE;
1453 
1454     return E_UNKNOWN_FACTORY;
1455 }
1456 
1457 /*-----------------------------------------------
1458     31.07.2003 14:39
1459 -----------------------------------------------*/
1460 SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByURL(const ::rtl::OUString&                                 sURL            ,
1461                                                                   const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
1462 {
1463     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
1464     if (!xSMGR.is())
1465         return E_UNKNOWN_FACTORY;
1466 
1467     css::uno::Reference< css::container::XNameAccess > xFilterCfg;
1468     css::uno::Reference< css::container::XNameAccess > xTypeCfg ;
1469     try
1470     {
1471         xFilterCfg = css::uno::Reference< css::container::XNameAccess >(
1472             xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory")), css::uno::UNO_QUERY);
1473         xTypeCfg = css::uno::Reference< css::container::XNameAccess >(
1474             xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.TypeDetection")), css::uno::UNO_QUERY);
1475     }
1476     catch(const css::uno::RuntimeException&)
1477         { throw; }
1478     catch(const css::uno::Exception&)
1479         { return E_UNKNOWN_FACTORY; }
1480 
1481     ::comphelper::SequenceAsHashMap stlDesc(lMediaDescriptor);
1482 
1483     // is there already a filter inside the descriptor?
1484     ::rtl::OUString sFilterName = stlDesc.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("FilterName"), ::rtl::OUString());
1485     if (sFilterName.getLength())
1486     {
1487         try
1488         {
1489             ::comphelper::SequenceAsHashMap stlFilterProps   (xFilterCfg->getByName(sFilterName));
1490             ::rtl::OUString                 sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("DocumentService"), ::rtl::OUString());
1491             SvtModuleOptions::EFactory      eApp             = SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService);
1492 
1493             if (eApp != E_UNKNOWN_FACTORY)
1494                 return eApp;
1495         }
1496         catch(const css::uno::RuntimeException&)
1497             { throw; }
1498         catch(const css::uno::Exception&)
1499             { /* do nothing here ... may the following code can help!*/ }
1500     }
1501 
1502     // is there already a type inside the descriptor?
1503     ::rtl::OUString sTypeName = stlDesc.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("TypeName"), ::rtl::OUString());
1504     if (!sTypeName.getLength())
1505     {
1506         // no :-(
1507         // start flat detection of URL
1508         css::uno::Reference< css::document::XTypeDetection > xDetect(xTypeCfg, css::uno::UNO_QUERY);
1509         sTypeName = xDetect->queryTypeByURL(sURL);
1510     }
1511 
1512     if (!sTypeName.getLength())
1513         return E_UNKNOWN_FACTORY;
1514 
1515     // yes - there is a type info
1516     // Try to find the preferred filter.
1517     try
1518     {
1519         ::comphelper::SequenceAsHashMap stlTypeProps     (xTypeCfg->getByName(sTypeName));
1520         ::rtl::OUString                 sPreferredFilter = stlTypeProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("PreferredFilter"), ::rtl::OUString());
1521         ::comphelper::SequenceAsHashMap stlFilterProps   (xFilterCfg->getByName(sPreferredFilter));
1522         ::rtl::OUString                 sDocumentService = stlFilterProps.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("DocumentService"), ::rtl::OUString());
1523         SvtModuleOptions::EFactory      eApp             = SvtModuleOptions::ClassifyFactoryByServiceName(sDocumentService);
1524 
1525         if (eApp != E_UNKNOWN_FACTORY)
1526             return eApp;
1527     }
1528     catch(const css::uno::RuntimeException&)
1529         { throw; }
1530     catch(const css::uno::Exception&)
1531         { /* do nothing here ... may the following code can help!*/ }
1532 
1533     // no filter/no type/no detection result => no fun :-)
1534     return E_UNKNOWN_FACTORY;
1535 }
1536 
1537 /*-----------------------------------------------
1538     31.07.2003 10:41
1539 -----------------------------------------------*/
1540 SvtModuleOptions::EFactory SvtModuleOptions::ClassifyFactoryByModel(const css::uno::Reference< css::frame::XModel >& xModel)
1541 {
1542     css::uno::Reference< css::lang::XServiceInfo > xInfo(xModel, css::uno::UNO_QUERY);
1543     if (!xInfo.is())
1544         return E_UNKNOWN_FACTORY;
1545 
1546     const css::uno::Sequence< ::rtl::OUString > lServices = xInfo->getSupportedServiceNames();
1547     const ::rtl::OUString*                      pServices = lServices.getConstArray();
1548 
1549     for (sal_Int32 i=0; i<lServices.getLength() ; ++i)
1550     {
1551         SvtModuleOptions::EFactory eApp = SvtModuleOptions::ClassifyFactoryByServiceName(pServices[i]);
1552         if (eApp != E_UNKNOWN_FACTORY)
1553             return eApp;
1554     }
1555 
1556     return E_UNKNOWN_FACTORY;
1557 }
1558 
1559 ::com::sun::star::uno::Sequence < ::rtl::OUString > SvtModuleOptions::GetAllServiceNames()
1560 {
1561     ::osl::MutexGuard aGuard( impl_GetOwnStaticMutex() );
1562     return m_pDataContainer->GetAllServiceNames();
1563 }
1564 
1565 ::rtl::OUString SvtModuleOptions::GetDefaultModuleName()
1566 {
1567 	::rtl::OUString aModule;
1568     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SWRITER))
1569         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITER);
1570     else
1571     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SCALC))
1572         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_CALC);
1573     else
1574     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SIMPRESS))
1575         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_IMPRESS);
1576     else
1577     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SDATABASE))
1578         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_DATABASE);
1579     else
1580     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SDRAW))
1581         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_DRAW);
1582     else
1583     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SWEB))
1584         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITERWEB);
1585     else
1586     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SGLOBAL))
1587         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_WRITERGLOBAL);
1588     else
1589     if (m_pDataContainer->IsModuleInstalled(SvtModuleOptions::E_SMATH))
1590         aModule = m_pDataContainer->GetFactoryShortName(SvtModuleOptions::E_MATH);
1591 	return aModule;
1592 }
1593 
1594