xref: /trunk/main/unotools/source/config/pathoptions.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 #ifndef GCC
31 #endif
32 
33 #include <unotools/pathoptions.hxx>
34 #include <unotools/configitem.hxx>
35 #include <unotools/configmgr.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/resmgr.hxx>
38 #include <tools/urlobj.hxx>
39 #include <com/sun/star/uno/Any.hxx>
40 #include <com/sun/star/uno/Sequence.hxx>
41 #include <osl/mutex.hxx>
42 #include <osl/file.hxx>
43 #include <unotools/localfilehelper.hxx>
44 #include <unotools/bootstrap.hxx>
45 
46 #include <unotools/ucbhelper.hxx>
47 #include <vos/process.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/componentcontext.hxx>
50 #include <com/sun/star/beans/XFastPropertySet.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
53 #include <com/sun/star/beans/XPropertySetInfo.hpp>
54 #include <com/sun/star/util/XStringSubstitution.hpp>
55 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 #include <com/sun/star/util/XMacroExpander.hpp>
57 #include <rtl/instance.hxx>
58 
59 #include <itemholder1.hxx>
60 
61 #include <vector>
62 #include <hash_map>
63 
64 using namespace osl;
65 using namespace utl;
66 using namespace rtl;
67 using namespace com::sun::star::uno;
68 using namespace com::sun::star::beans;
69 using namespace com::sun::star::util;
70 using namespace com::sun::star::lang;
71 
72 // define ----------------------------------------------------------------
73 
74 #define SEARCHPATH_DELIMITER            ';'
75 
76 #define ASCII_STR(s)                    OUString( RTL_CONSTASCII_USTRINGPARAM(s) )
77 
78 #define SIGN_STARTVARIABLE              ASCII_STR("$(")
79 #define SIGN_ENDVARIABLE                ASCII_STR(")")
80 
81 // Supported variables by the old SvtPathOptions implementation
82 #define SUBSTITUTE_INST                 "$(inst)"
83 #define SUBSTITUTE_PROG                 "$(prog)"
84 #define SUBSTITUTE_USER                 "$(user)"
85 #define SUBSTITUTE_INSTPATH             "$(instpath)"
86 #define SUBSTITUTE_PROGPATH             "$(progpath)"
87 #define SUBSTITUTE_USERPATH             "$(userpath)"
88 #define SUBSTITUTE_INSTURL              "$(insturl)"
89 #define SUBSTITUTE_PROGURL              "$(progurl)"
90 #define SUBSTITUTE_USERURL              "$(userurl)"
91 #define SUBSTITUTE_PATH                 "$(path)"
92 //#define   SUBSTITUTE_LANG                 "$(lang)"
93 #define SUBSTITUTE_LANGID               "$(langid)"
94 #define SUBSTITUTE_VLANG                "$(vlang)"
95 #define SUBSTITUTE_WORKDIRURL           "$(workdirurl)"
96 
97 #define STRPOS_NOTFOUND                 -1
98 
99 struct OUStringHashCode
100 {
101     size_t operator()( const ::rtl::OUString& sString ) const
102     {
103         return sString.hashCode();
104     }
105 };
106 
107 enum VarNameProperty
108 {
109     VAR_NEEDS_SYSTEM_PATH,
110     VAR_NEEDS_FILEURL
111 };
112 
113 class NameToHandleMap : public ::std::hash_map< ::rtl::OUString, sal_Int32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > >
114 {
115     public:
116         inline void free() { NameToHandleMap().swap( *this ); }
117 };
118 
119 class EnumToHandleMap : public ::std::hash_map< sal_Int32, sal_Int32, std::hash< sal_Int32 >, std::equal_to< sal_Int32 > >
120 {
121     public:
122         inline void free() { EnumToHandleMap().swap( *this ); }
123 };
124 
125 class VarNameToEnumMap : public ::std::hash_map< OUString, VarNameProperty, OUStringHashCode, ::std::equal_to< OUString > >
126 {
127     public:
128         inline void free() { VarNameToEnumMap().swap( *this ); }
129 };
130 
131 
132 // class SvtPathOptions_Impl ---------------------------------------------
133 class SvtPathOptions_Impl
134 {
135     private:
136         // Local variables to return const references
137         std::vector< String >               m_aPathArray;
138         Reference< XFastPropertySet >       m_xPathSettings;
139         Reference< XStringSubstitution >    m_xSubstVariables;
140         Reference< XMacroExpander >         m_xMacroExpander;
141         mutable EnumToHandleMap             m_aMapEnumToPropHandle;
142         VarNameToEnumMap                    m_aMapVarNamesToEnum;
143 
144         ::com::sun::star::lang::Locale                      m_aLocale;
145         String                              m_aEmptyString;
146         mutable ::osl::Mutex                m_aMutex;
147 
148     public:
149                         SvtPathOptions_Impl();
150 
151         // get the pathes, not const because of using a mutex
152         const String&   GetPath( SvtPathOptions::Pathes );
153         const String&   GetAddinPath() { return GetPath( SvtPathOptions::PATH_ADDIN ); }
154         const String&   GetAutoCorrectPath() { return GetPath( SvtPathOptions::PATH_AUTOCORRECT ); }
155         const String&   GetAutoTextPath() { return GetPath( SvtPathOptions::PATH_AUTOTEXT ); }
156         const String&   GetBackupPath() { return GetPath( SvtPathOptions::PATH_BACKUP ); }
157         const String&   GetBasicPath() { return GetPath( SvtPathOptions::PATH_BASIC ); }
158         const String&   GetBitmapPath() { return GetPath( SvtPathOptions::PATH_BITMAP ); }
159         const String&   GetConfigPath() { return GetPath( SvtPathOptions::PATH_CONFIG ); }
160         const String&   GetDictionaryPath() { return GetPath( SvtPathOptions::PATH_DICTIONARY ); }
161         const String&   GetFavoritesPath() { return GetPath( SvtPathOptions::PATH_FAVORITES ); }
162         const String&   GetFilterPath() { return GetPath( SvtPathOptions::PATH_FILTER ); }
163         const String&   GetGalleryPath() { return GetPath( SvtPathOptions::PATH_GALLERY ); }
164         const String&   GetGraphicPath() { return GetPath( SvtPathOptions::PATH_GRAPHIC ); }
165         const String&   GetHelpPath() { return GetPath( SvtPathOptions::PATH_HELP ); }
166         const String&   GetLinguisticPath() { return GetPath( SvtPathOptions::PATH_LINGUISTIC ); }
167         const String&   GetModulePath() { return GetPath( SvtPathOptions::PATH_MODULE ); }
168         const String&   GetPalettePath() { return GetPath( SvtPathOptions::PATH_PALETTE ); }
169         const String&   GetPluginPath() { return GetPath( SvtPathOptions::PATH_PLUGIN ); }
170         const String&   GetStoragePath() { return GetPath( SvtPathOptions::PATH_STORAGE ); }
171         const String&   GetTempPath() { return GetPath( SvtPathOptions::PATH_TEMP ); }
172         const String&   GetTemplatePath() { return GetPath( SvtPathOptions::PATH_TEMPLATE ); }
173         const String&   GetUserConfigPath() { return GetPath( SvtPathOptions::PATH_USERCONFIG ); }
174         const String&   GetWorkPath() { return GetPath( SvtPathOptions::PATH_WORK ); }
175         const String&   GetUIConfigPath() { return GetPath( SvtPathOptions::PATH_UICONFIG ); }
176         const String&   GetFingerprintPath() { return GetPath( SvtPathOptions::PATH_FINGERPRINT ); }
177 
178         // set the pathes
179         void            SetPath( SvtPathOptions::Pathes, const String& rNewPath );
180         void            SetAddinPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_ADDIN, rPath ); }
181         void            SetAutoCorrectPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOCORRECT, rPath ); }
182         void            SetAutoTextPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_AUTOTEXT, rPath ); }
183         void            SetBackupPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BACKUP, rPath ); }
184         void            SetBasicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BASIC, rPath ); }
185         void            SetBitmapPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_BITMAP, rPath ); }
186         void            SetConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_CONFIG, rPath ); }
187         void            SetDictionaryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_DICTIONARY, rPath ); }
188         void            SetFavoritesPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FAVORITES, rPath ); }
189         void            SetFilterPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_FILTER, rPath ); }
190         void            SetGalleryPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GALLERY, rPath ); }
191         void            SetGraphicPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_GRAPHIC, rPath ); }
192         void            SetHelpPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_HELP, rPath ); }
193         void            SetLinguisticPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_LINGUISTIC, rPath ); }
194         void            SetModulePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_MODULE, rPath ); }
195         void            SetPalettePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PALETTE, rPath ); }
196         void            SetPluginPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_PLUGIN, rPath ); }
197         void            SetStoragePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_STORAGE, rPath ); }
198         void            SetTempPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMP, rPath ); }
199         void            SetTemplatePath( const String& rPath ) { SetPath( SvtPathOptions::PATH_TEMPLATE, rPath ); }
200         void            SetUserConfigPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_USERCONFIG, rPath ); }
201         void            SetWorkPath( const String& rPath ) { SetPath( SvtPathOptions::PATH_WORK, rPath ); }
202 
203         rtl::OUString   SubstVar( const rtl::OUString& rVar ) const;
204         rtl::OUString   ExpandMacros( const rtl::OUString& rPath ) const;
205         rtl::OUString   UsePathVariables( const rtl::OUString& rPath ) const;
206 
207         ::com::sun::star::lang::Locale  GetLocale() const { return m_aLocale; }
208 
209         sal_Bool            IsPathReadonly(SvtPathOptions::Pathes ePath)const;
210 };
211 
212 // global ----------------------------------------------------------------
213 
214 static SvtPathOptions_Impl* pOptions = NULL;
215 static sal_Int32 nRefCount = 0;
216 
217 // functions -------------------------------------------------------------
218 struct PropertyStruct
219 {
220     const char*             pPropName;  // The ascii name of the Office path
221     SvtPathOptions::Pathes  ePath;      // The enum value used by SvtPathOptions
222 };
223 
224 struct VarNameAttribute
225 {
226     const char*             pVarName;       // The name of the path variable
227     VarNameProperty         eVarProperty;   // Which return value is needed by this path variable
228 };
229 
230 static PropertyStruct aPropNames[] =
231 {
232     { "Addin",          SvtPathOptions::PATH_ADDIN          },
233     { "AutoCorrect",    SvtPathOptions::PATH_AUTOCORRECT    },
234     { "AutoText",       SvtPathOptions::PATH_AUTOTEXT       },
235     { "Backup",         SvtPathOptions::PATH_BACKUP         },
236     { "Basic",          SvtPathOptions::PATH_BASIC          },
237     { "Bitmap",         SvtPathOptions::PATH_BITMAP         },
238     { "Config",         SvtPathOptions::PATH_CONFIG         },
239     { "Dictionary",     SvtPathOptions::PATH_DICTIONARY     },
240     { "Favorite",       SvtPathOptions::PATH_FAVORITES      },
241     { "Filter",         SvtPathOptions::PATH_FILTER         },
242     { "Gallery",        SvtPathOptions::PATH_GALLERY        },
243     { "Graphic",        SvtPathOptions::PATH_GRAPHIC        },
244     { "Help",           SvtPathOptions::PATH_HELP           },
245     { "Linguistic",     SvtPathOptions::PATH_LINGUISTIC     },
246     { "Module",         SvtPathOptions::PATH_MODULE         },
247     { "Palette",        SvtPathOptions::PATH_PALETTE        },
248     { "Plugin",         SvtPathOptions::PATH_PLUGIN         },
249     { "Storage",        SvtPathOptions::PATH_STORAGE        },
250     { "Temp",           SvtPathOptions::PATH_TEMP           },
251     { "Template",       SvtPathOptions::PATH_TEMPLATE       },
252     { "UserConfig",     SvtPathOptions::PATH_USERCONFIG     },
253     { "Work",           SvtPathOptions::PATH_WORK           },
254     { "UIConfig",       SvtPathOptions::PATH_UICONFIG       },
255     { "Fingerprint",    SvtPathOptions::PATH_FINGERPRINT    }
256 };
257 
258 static VarNameAttribute aVarNameAttribute[] =
259 {
260     { SUBSTITUTE_INSTPATH,  VAR_NEEDS_SYSTEM_PATH },    // $(instpath)
261     { SUBSTITUTE_PROGPATH,  VAR_NEEDS_SYSTEM_PATH },    // $(progpath)
262     { SUBSTITUTE_USERPATH,  VAR_NEEDS_SYSTEM_PATH },    // $(userpath)
263     { SUBSTITUTE_PATH,      VAR_NEEDS_SYSTEM_PATH },    // $(path)
264 };
265 
266 #if 0
267 // currently unused
268 static Sequence< OUString > GetPathPropertyNames()
269 {
270     const int nCount = sizeof( aPropNames ) / sizeof( PropertyStruct );
271     Sequence< OUString > aNames( nCount );
272     OUString* pNames = aNames.getArray();
273     for ( int i = 0; i < nCount; i++ )
274         pNames[i] = OUString::createFromAscii( aPropNames[i].pPropName );
275 
276     return aNames;
277 }
278 #endif
279 
280 // class SvtPathOptions_Impl ---------------------------------------------
281 
282 const String& SvtPathOptions_Impl::GetPath( SvtPathOptions::Pathes ePath )
283 {
284     ::osl::MutexGuard aGuard( m_aMutex );
285 
286     if ( ePath >= SvtPathOptions::PATH_COUNT )
287         return m_aEmptyString;
288 
289     OUString    aPathValue;
290     String      aResult;
291     sal_Int32   nHandle = m_aMapEnumToPropHandle[ (sal_Int32)ePath ];
292 
293     // Substitution is done by the service itself using the substition service
294     Any         a = m_xPathSettings->getFastPropertyValue( nHandle );
295     a >>= aPathValue;
296     if( ePath == SvtPathOptions::PATH_ADDIN     ||
297         ePath == SvtPathOptions::PATH_FILTER    ||
298         ePath == SvtPathOptions::PATH_HELP      ||
299         ePath == SvtPathOptions::PATH_MODULE    ||
300         ePath == SvtPathOptions::PATH_PLUGIN    ||
301         ePath == SvtPathOptions::PATH_STORAGE
302       )
303     {
304         // These office paths have to be converted to system pathes
305         utl::LocalFileHelper::ConvertURLToPhysicalName( aPathValue, aResult );
306         aPathValue = aResult;
307     }
308 
309     m_aPathArray[ ePath ] = aPathValue;
310     return m_aPathArray[ ePath ];
311 }
312 // -----------------------------------------------------------------------
313 sal_Bool SvtPathOptions_Impl::IsPathReadonly(SvtPathOptions::Pathes ePath)const
314 {
315     ::osl::MutexGuard aGuard( m_aMutex );
316     sal_Bool bReadonly = sal_False;
317     if ( ePath < SvtPathOptions::PATH_COUNT )
318     {
319         Reference<XPropertySet> xPrSet(m_xPathSettings, UNO_QUERY);
320         if(xPrSet.is())
321         {
322             Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
323             const char* pA = aPropNames[ePath].pPropName;
324             ::rtl::OUString sU = OUString::createFromAscii(pA);
325             Property aProperty = xInfo->getPropertyByName(sU);
326             bReadonly = 0 != (aProperty.Attributes & PropertyAttribute::READONLY);
327         }
328     }
329     return bReadonly;
330 }
331 // -----------------------------------------------------------------------
332 
333 void SvtPathOptions_Impl::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath )
334 {
335     ::osl::MutexGuard aGuard( m_aMutex );
336 
337     if ( ePath < SvtPathOptions::PATH_COUNT )
338     {
339         String      aResult;
340         OUString    aNewValue;
341         Any         a;
342 
343         switch ( ePath )
344         {
345             case SvtPathOptions::PATH_ADDIN:
346             case SvtPathOptions::PATH_FILTER:
347             case SvtPathOptions::PATH_HELP:
348             case SvtPathOptions::PATH_MODULE:
349             case SvtPathOptions::PATH_PLUGIN:
350             case SvtPathOptions::PATH_STORAGE:
351             {
352                 // These office paths have to be convert back to UCB-URL's
353                 utl::LocalFileHelper::ConvertPhysicalNameToURL( rNewPath, aResult );
354                 aNewValue = aResult;
355             }
356             break;
357 
358             default:
359                 aNewValue = rNewPath;
360         }
361 
362         // Resubstitution is done by the service itself using the substition service
363         a <<= aNewValue;
364         try
365         {
366             m_xPathSettings->setFastPropertyValue( m_aMapEnumToPropHandle[ (sal_Int32)ePath], a );
367         }
368         catch (const Exception&)
369         {
370         }
371     }
372 }
373 
374 //-------------------------------------------------------------------------
375 
376 OUString SvtPathOptions_Impl::ExpandMacros( const rtl::OUString& rPath ) const
377 {
378     ::rtl::OUString sExpanded( rPath );
379 
380     const INetURLObject aParser( rPath );
381     if ( aParser.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
382         sExpanded = m_xMacroExpander->expandMacros( aParser.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
383 
384     return sExpanded;
385 }
386 
387 //-------------------------------------------------------------------------
388 
389 OUString SvtPathOptions_Impl::UsePathVariables( const OUString& rPath ) const
390 {
391     return m_xSubstVariables->reSubstituteVariables( rPath );
392 }
393 
394 // -----------------------------------------------------------------------
395 
396 OUString SvtPathOptions_Impl::SubstVar( const OUString& rVar ) const
397 {
398     // Don't work at parameter-string directly. Copy it.
399     OUString aWorkText = rVar;
400 
401     // Convert the returned path to system path!
402     sal_Bool bConvertLocal = sal_False;
403 
404     // Search for first occure of "$(...".
405     sal_Int32 nPosition = aWorkText.indexOf( SIGN_STARTVARIABLE );  // = first position of "$(" in string
406     sal_Int32 nLength   = 0;                                        // = count of letters from "$(" to ")" in string
407 
408     // Have we found any variable like "$(...)"?
409     if ( nPosition != STRPOS_NOTFOUND )
410     {
411         // Yes; Get length of found variable.
412         // If no ")" was found - nLength is set to 0 by default! see before.
413         sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition );
414         if ( nEndPosition != STRPOS_NOTFOUND )
415             nLength = nEndPosition - nPosition + 1;
416     }
417 
418     // Is there another path variable?
419     while ( ( nPosition != STRPOS_NOTFOUND ) && ( nLength > 0 ) )
420     {
421         // YES; Get the next variable for replace.
422         OUString aReplacement;
423         OUString aSubString = aWorkText.copy( nPosition, nLength );
424         aSubString = aSubString.toAsciiLowerCase();
425 
426         // Look for special variable that needs a system path.
427         VarNameToEnumMap::const_iterator pIter = m_aMapVarNamesToEnum.find( aSubString );
428         if ( pIter != m_aMapVarNamesToEnum.end() )
429             bConvertLocal = sal_True;
430 
431         nPosition += nLength;
432 
433         // We must control index in string before call something at OUString!
434         // The OUString-implementation don't do it for us :-( but the result is not defined otherwise.
435         if ( nPosition + 1 > aWorkText.getLength() )
436         {
437             // Position is out of range. Break loop!
438             nPosition = STRPOS_NOTFOUND;
439             nLength = 0;
440         }
441         else
442         {
443             // Else; Position is valid. Search for next variable.
444             nPosition = aWorkText.indexOf( SIGN_STARTVARIABLE, nPosition );
445             // Have we found any variable like "$(...)"?
446             if ( nPosition != STRPOS_NOTFOUND )
447             {
448                 // Yes; Get length of found variable. If no ")" was found - nLength must set to 0!
449                 nLength = 0;
450                 sal_Int32 nEndPosition = aWorkText.indexOf( SIGN_ENDVARIABLE, nPosition );
451                 if ( nEndPosition != STRPOS_NOTFOUND )
452                     nLength = nEndPosition - nPosition + 1;
453             }
454         }
455     }
456 
457     aWorkText = m_xSubstVariables->substituteVariables( rVar, sal_False );
458 
459     if ( bConvertLocal )
460     {
461         // Convert the URL to a system path for special path variables
462         String aReturn;
463         utl::LocalFileHelper::ConvertURLToPhysicalName( aWorkText, aReturn );
464         return aReturn;
465     }
466 
467     return aWorkText;
468 }
469 
470 // -----------------------------------------------------------------------
471 
472 SvtPathOptions_Impl::SvtPathOptions_Impl() :
473     m_aPathArray( (sal_Int32)SvtPathOptions::PATH_COUNT )
474 {
475     Reference< XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory();
476 
477     // Create necessary services
478     m_xPathSettings = Reference< XFastPropertySet >( xSMgr->createInstance(
479                                                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
480                                                         "com.sun.star.util.PathSettings" ))),
481                                                 UNO_QUERY );
482     if ( !m_xPathSettings.is() )
483     {
484         // #112719#: check for existance
485         DBG_ERROR( "SvtPathOptions_Impl::SvtPathOptions_Impl(): #112719# happened again!" );
486         throw RuntimeException(
487             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Service com.sun.star.util.PathSettings cannot be created" )),
488             Reference< XInterface >() );
489     }
490 
491     ::comphelper::ComponentContext aContext( xSMgr );
492     m_xSubstVariables.set( aContext.createComponent( "com.sun.star.util.PathSubstitution" ), UNO_QUERY_THROW );
493     m_xMacroExpander.set( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY_THROW );
494 
495     // Create temporary hash map to have a mapping between property names and property handles
496     Reference< XPropertySet > xPropertySet = Reference< XPropertySet >( m_xPathSettings, UNO_QUERY );
497     Reference< XPropertySetInfo > xPropSetInfo = xPropertySet->getPropertySetInfo();
498     Sequence< Property > aPathPropSeq = xPropSetInfo->getProperties();
499 
500     NameToHandleMap aTempHashMap;
501     for ( sal_Int32 n = 0; n < aPathPropSeq.getLength(); n++ )
502     {
503         const com::sun::star::beans::Property& aProperty = aPathPropSeq[n];
504         aTempHashMap.insert( NameToHandleMap::value_type( aProperty.Name, aProperty.Handle ));
505     }
506 
507     // Create mapping between internal enum (SvtPathOptions::Pathes) and property handle
508     sal_Int32 nCount = sizeof( aPropNames ) / sizeof( PropertyStruct );
509     sal_Int32 i;
510     for ( i = 0; i < nCount; i++ )
511     {
512         NameToHandleMap::const_iterator pIter =
513             aTempHashMap.find( rtl::OUString::createFromAscii( aPropNames[i].pPropName ));
514 
515         if ( pIter != aTempHashMap.end() )
516         {
517             sal_Int32 nHandle   = pIter->second;
518             sal_Int32 nEnum     = aPropNames[i].ePath;
519             m_aMapEnumToPropHandle.insert( EnumToHandleMap::value_type( nEnum, nHandle ));
520         }
521     }
522 
523     // Create hash map for path variables that need a system path as a return value!
524     nCount = sizeof( aVarNameAttribute ) / sizeof( VarNameAttribute );
525     for ( i = 0; i < nCount; i++ )
526     {
527         m_aMapVarNamesToEnum.insert( VarNameToEnumMap::value_type(
528                 OUString::createFromAscii( aVarNameAttribute[i].pVarName ),
529                 aVarNameAttribute[i].eVarProperty ));
530     }
531 
532     // Set language type!
533     Any aLocale = ConfigManager::GetConfigManager()->GetDirectConfigProperty( ConfigManager::LOCALE );
534     OUString aLocaleStr;
535     if ( aLocale >>= aLocaleStr )
536     {
537         sal_Int32 nIndex = 0;
538         m_aLocale.Language = aLocaleStr.getToken(0, '-', nIndex );
539         m_aLocale.Country = aLocaleStr.getToken(0, '-', nIndex );
540         m_aLocale.Variant = aLocaleStr.getToken(0, '-', nIndex );
541     }
542     else
543     {
544         DBG_ERRORFILE( "wrong any type" );
545         m_aLocale.Language = OStringToOUString(OString("en"), RTL_TEXTENCODING_UTF8);
546         m_aLocale.Country =  OStringToOUString(OString("US"), RTL_TEXTENCODING_UTF8);
547         m_aLocale.Variant =  OStringToOUString(OString(""), RTL_TEXTENCODING_UTF8);
548     }
549 }
550 
551 // -----------------------------------------------------------------------
552 
553 // class SvtPathOptions --------------------------------------------------
554 
555 namespace { struct lclMutex : public rtl::Static< ::osl::Mutex, lclMutex > {}; }
556 
557 SvtPathOptions::SvtPathOptions()
558 {
559     // Global access, must be guarded (multithreading)
560     ::osl::MutexGuard aGuard( lclMutex::get() );
561     if ( !pOptions )
562     {
563         pOptions = new SvtPathOptions_Impl;
564         ItemHolder1::holdConfigItem(E_PATHOPTIONS);
565     }
566     ++nRefCount;
567     pImp = pOptions;
568 }
569 
570 // -----------------------------------------------------------------------
571 
572 SvtPathOptions::~SvtPathOptions()
573 {
574     // Global access, must be guarded (multithreading)
575     ::osl::MutexGuard aGuard( lclMutex::get() );
576     if ( !--nRefCount )
577     {
578         DELETEZ( pOptions );
579     }
580 }
581 
582 // -----------------------------------------------------------------------
583 
584 const String& SvtPathOptions::GetAddinPath() const
585 {
586     return pImp->GetAddinPath();
587 }
588 
589 // -----------------------------------------------------------------------
590 
591 const String& SvtPathOptions::GetAutoCorrectPath() const
592 {
593     return pImp->GetAutoCorrectPath();
594 }
595 
596 // -----------------------------------------------------------------------
597 
598 const String& SvtPathOptions::GetAutoTextPath() const
599 {
600     return pImp->GetAutoTextPath();
601 }
602 
603 // -----------------------------------------------------------------------
604 
605 const String& SvtPathOptions::GetBackupPath() const
606 {
607     return pImp->GetBackupPath();
608 }
609 
610 // -----------------------------------------------------------------------
611 
612 const String& SvtPathOptions::GetBasicPath() const
613 {
614     return pImp->GetBasicPath();
615 }
616 
617 // -----------------------------------------------------------------------
618 
619 const String& SvtPathOptions::GetBitmapPath() const
620 {
621     return pImp->GetBitmapPath();
622 }
623 
624 // -----------------------------------------------------------------------
625 
626 const String& SvtPathOptions::GetConfigPath() const
627 {
628     return pImp->GetConfigPath();
629 }
630 
631 // -----------------------------------------------------------------------
632 
633 const String& SvtPathOptions::GetDictionaryPath() const
634 {
635     return pImp->GetDictionaryPath();
636 }
637 
638 // -----------------------------------------------------------------------
639 
640 const String& SvtPathOptions::GetFavoritesPath() const
641 {
642     return pImp->GetFavoritesPath();
643 }
644 
645 // -----------------------------------------------------------------------
646 
647 const String& SvtPathOptions::GetFilterPath() const
648 {
649     return pImp->GetFilterPath();
650 }
651 
652 // -----------------------------------------------------------------------
653 
654 const String& SvtPathOptions::GetGalleryPath() const
655 {
656     return pImp->GetGalleryPath();
657 }
658 
659 // -----------------------------------------------------------------------
660 
661 const String& SvtPathOptions::GetGraphicPath() const
662 {
663     return pImp->GetGraphicPath();
664 }
665 
666 // -----------------------------------------------------------------------
667 
668 const String& SvtPathOptions::GetHelpPath() const
669 {
670     return pImp->GetHelpPath();
671 }
672 
673 // -----------------------------------------------------------------------
674 
675 const String& SvtPathOptions::GetLinguisticPath() const
676 {
677     return pImp->GetLinguisticPath();
678 }
679 
680 // -----------------------------------------------------------------------
681 
682 const String& SvtPathOptions::GetFingerprintPath() const
683 {
684     return pImp->GetFingerprintPath();
685 }
686 
687 // -----------------------------------------------------------------------
688 
689 const String& SvtPathOptions::GetModulePath() const
690 {
691     return pImp->GetModulePath();
692 }
693 
694 // -----------------------------------------------------------------------
695 
696 const String& SvtPathOptions::GetPalettePath() const
697 {
698     return pImp->GetPalettePath();
699 }
700 
701 // -----------------------------------------------------------------------
702 
703 const String& SvtPathOptions::GetPluginPath() const
704 {
705     return pImp->GetPluginPath();
706 }
707 
708 // -----------------------------------------------------------------------
709 
710 const String& SvtPathOptions::GetStoragePath() const
711 {
712     return pImp->GetStoragePath();
713 }
714 
715 // -----------------------------------------------------------------------
716 
717 const String& SvtPathOptions::GetTempPath() const
718 {
719     return pImp->GetTempPath();
720 }
721 
722 // -----------------------------------------------------------------------
723 
724 const String& SvtPathOptions::GetTemplatePath() const
725 {
726     return pImp->GetTemplatePath();
727 }
728 
729 // -----------------------------------------------------------------------
730 
731 const String& SvtPathOptions::GetUserConfigPath() const
732 {
733     return pImp->GetUserConfigPath();
734 }
735 
736 const String& SvtPathOptions::GetUIConfigPath() const
737 {
738     return pImp->GetUIConfigPath();
739 }
740 
741 // -----------------------------------------------------------------------
742 
743 const String& SvtPathOptions::GetWorkPath() const
744 {
745     return pImp->GetWorkPath();
746 }
747 
748 // -----------------------------------------------------------------------
749 
750 void SvtPathOptions::SetAddinPath( const String& rPath )
751 {
752     pImp->SetAddinPath( rPath );
753 }
754 
755 // -----------------------------------------------------------------------
756 
757 void SvtPathOptions::SetAutoCorrectPath( const String& rPath )
758 {
759     pImp->SetAutoCorrectPath( rPath );
760 }
761 
762 // -----------------------------------------------------------------------
763 
764 void SvtPathOptions::SetAutoTextPath( const String& rPath )
765 {
766     pImp->SetAutoTextPath( rPath );
767 }
768 
769 // -----------------------------------------------------------------------
770 
771 void SvtPathOptions::SetBackupPath( const String& rPath )
772 {
773     pImp->SetBackupPath( rPath );
774 }
775 
776 // -----------------------------------------------------------------------
777 
778 void SvtPathOptions::SetBasicPath( const String& rPath )
779 {
780     pImp->SetBasicPath( rPath );
781 }
782 
783 // -----------------------------------------------------------------------
784 
785 void SvtPathOptions::SetBitmapPath( const String& rPath )
786 {
787     pImp->SetBitmapPath( rPath );
788 }
789 
790 // -----------------------------------------------------------------------
791 
792 void SvtPathOptions::SetConfigPath( const String& rPath )
793 {
794     pImp->SetConfigPath( rPath );
795 }
796 
797 // -----------------------------------------------------------------------
798 
799 void SvtPathOptions::SetDictionaryPath( const String& rPath )
800 {
801     pImp->SetDictionaryPath( rPath );
802 }
803 
804 // -----------------------------------------------------------------------
805 
806 void SvtPathOptions::SetFavoritesPath( const String& rPath )
807 {
808     pImp->SetFavoritesPath( rPath );
809 }
810 
811 // -----------------------------------------------------------------------
812 
813 void SvtPathOptions::SetFilterPath( const String& rPath )
814 {
815     pImp->SetFilterPath( rPath );
816 }
817 
818 // -----------------------------------------------------------------------
819 
820 void SvtPathOptions::SetGalleryPath( const String& rPath )
821 {
822     pImp->SetGalleryPath( rPath );
823 }
824 
825 // -----------------------------------------------------------------------
826 
827 void SvtPathOptions::SetGraphicPath( const String& rPath )
828 {
829     pImp->SetGraphicPath( rPath );
830 }
831 
832 // -----------------------------------------------------------------------
833 
834 void SvtPathOptions::SetHelpPath( const String& rPath )
835 {
836     pImp->SetHelpPath( rPath );
837 }
838 
839 // -----------------------------------------------------------------------
840 
841 void SvtPathOptions::SetLinguisticPath( const String& rPath )
842 {
843     pImp->SetLinguisticPath( rPath );
844 }
845 
846 // -----------------------------------------------------------------------
847 
848 void SvtPathOptions::SetModulePath( const String& rPath )
849 {
850     pImp->SetModulePath( rPath );
851 }
852 
853 // -----------------------------------------------------------------------
854 
855 void SvtPathOptions::SetPalettePath( const String& rPath )
856 {
857     pImp->SetPalettePath( rPath );
858 }
859 
860 // -----------------------------------------------------------------------
861 
862 void SvtPathOptions::SetPluginPath( const String& rPath )
863 {
864     pImp->SetPluginPath( rPath );
865 }
866 
867 // -----------------------------------------------------------------------
868 
869 void SvtPathOptions::SetStoragePath( const String& rPath )
870 {
871     pImp->SetStoragePath( rPath );
872 }
873 
874 // -----------------------------------------------------------------------
875 
876 void SvtPathOptions::SetTempPath( const String& rPath )
877 {
878     pImp->SetTempPath( rPath );
879 }
880 
881 // -----------------------------------------------------------------------
882 
883 void SvtPathOptions::SetTemplatePath( const String& rPath )
884 {
885     pImp->SetTemplatePath( rPath );
886 }
887 
888 // -----------------------------------------------------------------------
889 
890 void SvtPathOptions::SetUserConfigPath( const String& rPath )
891 {
892     pImp->SetUserConfigPath( rPath );
893 }
894 
895 // -----------------------------------------------------------------------
896 
897 void SvtPathOptions::SetWorkPath( const String& rPath )
898 {
899     pImp->SetWorkPath( rPath );
900 }
901 
902 // -----------------------------------------------------------------------
903 
904 String SvtPathOptions::SubstituteVariable( const String& rVar ) const
905 {
906     String aRet = pImp->SubstVar( rVar );
907     return aRet;
908 }
909 
910 // -----------------------------------------------------------------------
911 
912 String SvtPathOptions::ExpandMacros( const String& rPath ) const
913 {
914     return pImp->ExpandMacros( rPath );
915 }
916 
917 // -----------------------------------------------------------------------
918 
919 String SvtPathOptions::UseVariable( const String& rPath ) const
920 {
921     String aRet = pImp->UsePathVariables( rPath );
922     return aRet;
923 }
924 
925 // -----------------------------------------------------------------------
926 
927 sal_Bool SvtPathOptions::SearchFile( String& rIniFile, Pathes ePath )
928 {
929     // check parameter: empty inifile name?
930     if ( !rIniFile.Len() )
931     {
932         DBG_ERRORFILE( "SvtPathOptions::SearchFile(): invalid parameter" );
933         return sal_False;
934     }
935 
936     String aIniFile = pImp->SubstVar( rIniFile );
937     sal_Bool bRet = sal_False;
938 
939     switch ( ePath )
940     {
941         case PATH_USERCONFIG:
942         {
943             // path is a URL
944             bRet = sal_True;
945             INetURLObject aObj( GetUserConfigPath() );
946             xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' );
947             for ( i = 0; i < nCount; ++i )
948                 aObj.insertName( aIniFile.GetToken( i, '/' ) );
949 
950             if ( !::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
951             {
952                 aObj.SetSmartURL( GetConfigPath() );
953                 aObj.insertName( aIniFile );
954                 bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
955             }
956 
957             if ( bRet )
958                 rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE );
959 
960             break;
961         }
962 
963         default:
964         {
965             String aPath;
966             switch ( ePath )
967             {
968                 case PATH_ADDIN:        aPath = GetAddinPath();         break;
969                 case PATH_AUTOCORRECT:  aPath = GetAutoCorrectPath();   break;
970                 case PATH_AUTOTEXT:     aPath = GetAutoTextPath();      break;
971                 case PATH_BACKUP:       aPath = GetBackupPath();        break;
972                 case PATH_BASIC:        aPath = GetBasicPath();         break;
973                 case PATH_BITMAP:       aPath = GetBitmapPath();        break;
974                 case PATH_CONFIG:       aPath = GetConfigPath();        break;
975                 case PATH_DICTIONARY:   aPath = GetDictionaryPath();    break;
976                 case PATH_FAVORITES:    aPath = GetFavoritesPath();     break;
977                 case PATH_FILTER:       aPath = GetFilterPath();        break;
978                 case PATH_GALLERY:      aPath = GetGalleryPath();       break;
979                 case PATH_GRAPHIC:      aPath = GetGraphicPath();       break;
980                 case PATH_HELP:         aPath = GetHelpPath();          break;
981                 case PATH_LINGUISTIC:   aPath = GetLinguisticPath();    break;
982                 case PATH_MODULE:       aPath = GetModulePath();        break;
983                 case PATH_PALETTE:      aPath = GetPalettePath();       break;
984                 case PATH_PLUGIN:       aPath = GetPluginPath();        break;
985                 case PATH_STORAGE:      aPath = GetStoragePath();       break;
986                 case PATH_TEMP:         aPath = GetTempPath();          break;
987                 case PATH_TEMPLATE:     aPath = GetTemplatePath();      break;
988                 case PATH_WORK:         aPath = GetWorkPath();          break;
989                 case PATH_UICONFIG:     aPath = GetUIConfigPath();      break;
990                 case PATH_FINGERPRINT:  aPath = GetFingerprintPath();   break;
991                 case PATH_USERCONFIG:/*-Wall???*/           break;
992                 case PATH_COUNT: /*-Wall???*/ break;
993             }
994 
995             sal_uInt16 j, nIdx = 0, nTokenCount = aPath.GetTokenCount( SEARCHPATH_DELIMITER );
996             for ( j = 0; j < nTokenCount; ++j )
997             {
998                 sal_Bool bIsURL = sal_True;
999                 String aPathToken = aPath.GetToken( 0, SEARCHPATH_DELIMITER, nIdx );
1000                 INetURLObject aObj( aPathToken );
1001                 if ( aObj.HasError() )
1002                 {
1003                     bIsURL = sal_False;
1004                     String aURL;
1005                     if ( LocalFileHelper::ConvertPhysicalNameToURL( aPathToken, aURL ) )
1006                         aObj.SetURL( aURL );
1007                 }
1008                 if ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_EXPAND )
1009                 {
1010                     ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
1011                     Reference< XMacroExpander > xMacroExpander( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY );
1012                     OSL_ENSURE( xMacroExpander.is(), "SvtPathOptions::SearchFile: unable to access the MacroExpander singleton!" );
1013                     if ( xMacroExpander.is() )
1014                     {
1015                         const ::rtl::OUString sExpandedPath = xMacroExpander->expandMacros( aObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ) );
1016                         aObj.SetURL( sExpandedPath );
1017                     }
1018                 }
1019 
1020                 xub_StrLen i, nCount = aIniFile.GetTokenCount( '/' );
1021                 for ( i = 0; i < nCount; ++i )
1022                     aObj.insertName( aIniFile.GetToken( i, '/' ) );
1023                 bRet = ::utl::UCBContentHelper::Exists( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1024 
1025                 if ( bRet )
1026                 {
1027                     if ( !bIsURL )
1028                         ::utl::LocalFileHelper::ConvertURLToPhysicalName(
1029                                             aObj.GetMainURL( INetURLObject::NO_DECODE ), rIniFile );
1030                     else
1031                         rIniFile = aObj.GetMainURL( INetURLObject::NO_DECODE );
1032                     break;
1033                 }
1034             }
1035         }
1036     }
1037 
1038     return bRet;
1039 }
1040 
1041 // -----------------------------------------------------------------------
1042 
1043 ::com::sun::star::lang::Locale SvtPathOptions::GetLocale() const
1044 {
1045     return pImp->GetLocale();
1046 }
1047 // -----------------------------------------------------------------------
1048 sal_Bool SvtPathOptions::IsPathReadonly(Pathes ePath)const
1049 {
1050     return pImp->IsPathReadonly(ePath);
1051 }
1052 // -----------------------------------------------------------------------
1053 const String& SvtPathOptions::GetPath(Pathes ePath)const
1054 {
1055     return pImp->GetPath(ePath);
1056 }
1057 // -----------------------------------------------------------------------
1058 void SvtPathOptions::SetPath( SvtPathOptions::Pathes ePath, const String& rNewPath )
1059 {
1060     pImp->SetPath(ePath, rNewPath);
1061 }
1062 
1063 // class PathService -----------------------------------------------------
1064 #include <com/sun/star/frame/XConfigManager.hpp>
1065 #include <com/sun/star/lang/XServiceInfo.hpp>
1066 #include <cppuhelper/implbase2.hxx>
1067 
1068 class PathService : public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XConfigManager, ::com::sun::star::lang::XServiceInfo >
1069 {
1070     virtual ::rtl::OUString SAL_CALL    getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
1071     virtual sal_Bool SAL_CALL           supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
1072     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
1073                                         getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
1074     virtual ::rtl::OUString SAL_CALL    substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException);
1075     virtual void SAL_CALL               addPropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
1076     virtual void SAL_CALL               removePropertyChangeListener( const ::rtl::OUString& sKeyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::uno::RuntimeException);
1077     virtual void SAL_CALL               flush(  ) throw(::com::sun::star::uno::RuntimeException);
1078 };
1079 
1080 // class PathService -----------------------------------------------------
1081 
1082 void SAL_CALL PathService::addPropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {}
1083 void SAL_CALL PathService::removePropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) throw(::com::sun::star::uno::RuntimeException) {}
1084 void SAL_CALL PathService::flush(  ) throw(::com::sun::star::uno::RuntimeException) {}
1085 
1086 ::rtl::OUString SAL_CALL PathService::substituteVariables( const ::rtl::OUString& sText ) throw(::com::sun::star::uno::RuntimeException)
1087 {
1088     return SvtPathOptions().SubstituteVariable( sText );
1089 }
1090 
1091 ::rtl::OUString SAL_CALL PathService::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException)
1092 {
1093     return OUString::createFromAscii("com.sun.star.comp.unotools.PathService");
1094 }
1095 
1096 sal_Bool SAL_CALL PathService::supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException)
1097 {
1098     if ( ServiceName.compareToAscii("com.sun.star.config.SpecialConfigManager") == COMPARE_EQUAL )
1099         return sal_True;
1100     else
1101         return sal_False;
1102 }
1103 
1104 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL PathService::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
1105 {
1106     Sequence< OUString > aRet(1);
1107     *aRet.getArray() = OUString::createFromAscii("com.sun.star.config.SpecialConfigManager");
1108     return aRet;
1109 }
1110