1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gconflayer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_shell.hxx"
34 #include "gconflayer.hxx"
35 #include <com/sun/star/configuration/backend/PropertyInfo.hpp>
37 #ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XLAYERCONTENTDESCIBER_HPP_
38 #include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>
40 #include <rtl/strbuf.hxx>
41 #include <rtl/ustrbuf.hxx>
42 #include <osl/security.hxx>
43 #include <osl/file.hxx>
44 #include <osl/thread.h>
45 #include <com/sun/star/uno/Sequence.hxx>
51 //==============================================================================
53 GconfLayer::GconfLayer( const uno::Reference
<uno::XComponentContext
>& xContext
,
54 const ConfigurationValue pConfigurationValuesList
[],
55 const sal_Int32 nConfigurationValues
,
56 const char * pPreloadValuesList
[] )
57 :m_pConfigurationValuesList( pConfigurationValuesList
)
58 ,m_nConfigurationValues( nConfigurationValues
)
59 ,m_pPreloadValuesList( pPreloadValuesList
)
61 //Create instance of LayerContentDescriber Service
62 rtl::OUString
const k_sLayerDescriberService( RTL_CONSTASCII_USTRINGPARAM(
63 "com.sun.star.comp.configuration.backend.LayerDescriber" ) );
65 typedef uno::Reference
<backend::XLayerContentDescriber
> LayerDescriber
;
66 uno::Reference
< lang::XMultiComponentFactory
> xServiceManager
= xContext
->getServiceManager();
67 if( xServiceManager
.is() )
69 m_xLayerContentDescriber
= LayerDescriber::query(
70 xServiceManager
->createInstanceWithContext( k_sLayerDescriberService
, xContext
) );
74 OSL_TRACE( "Could not retrieve ServiceManager" );
78 //------------------------------------------------------------------------------
80 static OUString
xdg_user_dir_lookup (const char *type
)
87 osl::Security aSecurity
;
90 OUString aDocumentsDirURL
;
91 OUString aConfigFileURL
;
92 OUStringBuffer aUserDirBuf
;
94 if (!aSecurity
.getHomeDir( aHomeDirURL
) )
96 osl::FileBase::getFileURLFromSystemPath(rtl::OUString::createFromAscii("/tmp"), aDocumentsDirURL
);
97 return aDocumentsDirURL
;
100 config_home
= getenv ("XDG_CONFIG_HOME");
101 if (config_home
== NULL
|| config_home
[0] == 0)
103 aConfigFileURL
= OUString(aHomeDirURL
);
104 aConfigFileURL
+= OUString::createFromAscii( "/.config/user-dirs.dirs" );
108 aConfigFileURL
= OUString::createFromAscii(config_home
);
109 aConfigFileURL
+= OUString::createFromAscii( "/user-dirs.dirs" );
112 if(osl_File_E_None
== osl_openFile(aConfigFileURL
.pData
, &handle
, osl_File_OpenFlag_Read
))
114 rtl::ByteSequence seq
;
115 while (osl_File_E_None
== osl_readLine(handle
, (sal_Sequence
**)&seq
))
117 /* Remove newline at end */
118 int len
= seq
.getLength();
119 if(len
>0 && seq
[len
-1] == '\n')
122 p
= (char *)seq
.getArray();
124 while (*p
== ' ' || *p
== '\t')
127 if (strncmp (p
, "XDG_", 4) != 0)
130 if (strncmp (p
, type
, strlen (type
)) != 0)
133 if (strncmp (p
, "_DIR", 4) != 0)
137 while (*p
== ' ' || *p
== '\t')
144 while (*p
== ' ' || *p
== '\t')
152 if (strncmp (p
, "$HOME/", 6) == 0)
162 aUserDirBuf
= OUStringBuffer(aHomeDirURL
);
163 aUserDirBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/" ) );
167 aUserDirBuf
= OUStringBuffer();
170 while (*p
&& *p
!= '"')
172 if ((*p
== '\\') && (*(p
+1) != 0))
174 aUserDirBuf
.append((sal_Unicode
)*p
++);
177 osl_closeFile(handle
);
182 if (aUserDirBuf
.getLength()>0 && !bError
)
184 aDocumentsDirURL
= aUserDirBuf
.makeStringAndClear();
185 osl::Directory
aDocumentsDir( aDocumentsDirURL
);
186 if( osl::FileBase::E_None
== aDocumentsDir
.open() )
187 return aDocumentsDirURL
;
190 /* Special case desktop for historical compatibility */
191 if (strcmp (type
, "DESKTOP") == 0)
193 aUserDirBuf
= OUStringBuffer(aHomeDirURL
);
194 aUserDirBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/Desktop" ) );
195 return aUserDirBuf
.makeStringAndClear();
199 aUserDirBuf
= OUStringBuffer(aHomeDirURL
);
200 aUserDirBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/Documents" ) );
201 return aUserDirBuf
.makeStringAndClear();
205 //------------------------------------------------------------------------------
207 uno::Any
makeAnyOfGconfValue( GConfValue
*aGconfValue
)
209 switch( aGconfValue
->type
)
211 case GCONF_VALUE_BOOL
:
212 return uno::makeAny( (sal_Bool
) gconf_value_get_bool( aGconfValue
) );
214 case GCONF_VALUE_INT
:
215 return uno::makeAny( (sal_Int32
) gconf_value_get_int( aGconfValue
) );
217 case GCONF_VALUE_STRING
:
218 return uno::makeAny( OStringToOUString( rtl::OString(
219 gconf_value_get_string(aGconfValue
) ), RTL_TEXTENCODING_UTF8
) );
222 fprintf( stderr
, "makeAnyOfGconfValue: Type not handled.\n" );
229 //------------------------------------------------------------------------------
231 static void splitFontName( GConfValue
*aGconfValue
, rtl::OUString
&rName
, sal_Int16
&rHeight
)
233 rtl::OString
aFont( gconf_value_get_string( aGconfValue
) );
235 sal_Int32 nIdx
= aFont
.lastIndexOf( ' ' );
236 if (nIdx
< 1) { // urk
238 nIdx
= aFont
.getLength();
240 rtl::OString aSize
= aFont
.copy( nIdx
+ 1 );
241 rHeight
= static_cast<sal_Int16
>( aSize
.toInt32() );
244 rName
= rtl::OStringToOUString( aFont
.copy( 0, nIdx
), RTL_TEXTENCODING_UTF8
);
247 //------------------------------------------------------------------------------
249 uno::Any
translateToOOo( const ConfigurationValue aValue
, GConfValue
*aGconfValue
)
252 switch( aValue
.nSettingId
)
254 case SETTING_PROXY_MODE
:
256 rtl::OUString aProxyMode
;
257 uno::Any aOriginalValue
= makeAnyOfGconfValue( aGconfValue
);
258 aOriginalValue
>>= aProxyMode
;
260 if( aProxyMode
.equals( rtl::OUString::createFromAscii( "manual" ) ) )
261 return uno::makeAny( (sal_Int32
) 1 );
262 else if( aProxyMode
.equals( rtl::OUString::createFromAscii( "none" ) ) )
263 return uno::makeAny( (sal_Int32
) 0 );
267 case SETTING_NO_PROXY_FOR
:
269 rtl::OStringBuffer aBuffer
;
270 if( (GCONF_VALUE_LIST
== aGconfValue
->type
) && (GCONF_VALUE_STRING
== gconf_value_get_list_type(aGconfValue
)) )
272 GSList
* list
= gconf_value_get_list(aGconfValue
);
273 for(; list
; list
= g_slist_next(list
))
275 aBuffer
.append(gconf_value_get_string((GConfValue
*) list
->data
));
278 // Remove trailing ";"
279 aBuffer
.setLength(aBuffer
.getLength()-1);
280 return uno::makeAny(rtl::OStringToOUString(aBuffer
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
));
283 g_warning( "unexpected type for ignore_hosts" );
287 case SETTING_MAILER_PROGRAM
:
289 rtl::OUString aMailer
;
290 uno::Any aOriginalValue
= makeAnyOfGconfValue( aGconfValue
);
291 aOriginalValue
>>= aMailer
;
292 sal_Int32 nIndex
= 0;
293 return uno::makeAny( aMailer
.getToken( 0, ' ', nIndex
) );
296 #ifdef ENABLE_LOCKDOWN
297 // "short" values need to be returned a sal_Int16
298 case SETTING_FONT_ANTI_ALIASING_MIN_PIXEL
:
299 case SETTING_SYMBOL_SET
:
301 sal_Int32 nShortValue
;
302 uno::Any aOriginalValue
= makeAnyOfGconfValue( aGconfValue
);
303 aOriginalValue
>>= nShortValue
;
304 return uno::makeAny( (sal_Int16
) nShortValue
);
307 #endif // ENABLE_LOCKDOWN
309 // "boolean" values that need a string to be returned
310 case SETTING_ENABLE_ACCESSIBILITY
:
311 #ifdef ENABLE_LOCKDOWN
312 case SETTING_DISABLE_PRINTING
:
313 #endif // ENABLE_LOCKDOWN
315 sal_Bool bBooleanValue
= false;
316 uno::Any aOriginalValue
= makeAnyOfGconfValue( aGconfValue
);
317 aOriginalValue
>>= bBooleanValue
;
318 return uno::makeAny( rtl::OUString::valueOf( (sal_Bool
) bBooleanValue
) );
321 case SETTING_WORK_DIRECTORY
:
323 rtl::OUString aDocumentsDirURL
= xdg_user_dir_lookup("DOCUMENTS");
325 return uno::makeAny( aDocumentsDirURL
);
328 case SETTING_USER_GIVENNAME
:
330 rtl::OUString
aCompleteName( rtl::OStringToOUString(
331 g_get_real_name(), osl_getThreadTextEncoding() ) );
332 sal_Int32 nIndex
= 0;
333 rtl::OUString aGivenName
;
335 aGivenName
= aCompleteName
.getToken( 0, ' ', nIndex
);
336 while ( nIndex
== 0 );
338 return uno::makeAny( aGivenName
);
342 case SETTING_USER_SURNAME
:
344 rtl::OUString
aCompleteName( rtl::OStringToOUString(
345 g_get_real_name(), osl_getThreadTextEncoding() ) );
346 sal_Int32 nIndex
= 0;
347 rtl::OUString aSurname
;
349 aSurname
= aCompleteName
.getToken( 0, ' ', nIndex
);
350 while ( nIndex
>= 0 );
352 return uno::makeAny( aSurname
);
355 case SETTING_SOURCEVIEWFONT_NAME
:
356 case SETTING_SOURCEVIEWFONT_HEIGHT
:
361 splitFontName (aGconfValue
, aName
, nHeight
);
362 if (aValue
.nSettingId
== SETTING_SOURCEVIEWFONT_NAME
)
363 return uno::makeAny( aName
);
365 return uno::makeAny( nHeight
);
370 fprintf( stderr
, "Unhandled setting to translate.\n" );
377 //------------------------------------------------------------------------------
379 sal_Bool SAL_CALL
isDependencySatisfied( const ConfigurationValue aValue
)
381 switch( aValue
.nDependsOn
)
383 case SETTING_PROXY_MODE
:
385 GConfClient
* aClient
= GconfBackend::getGconfClient();
386 GConfValue
* aGconfValue
= gconf_client_get( aClient
, GCONF_PROXY_MODE_KEY
, NULL
);
388 if ( aGconfValue
!= NULL
)
390 bool bOk
= g_strcasecmp( "manual", gconf_value_get_string( aGconfValue
) ) == 0;
391 gconf_value_free( aGconfValue
);
392 if (bOk
) return sal_True
;
397 case SETTING_WORK_DIRECTORY
:
399 rtl::OUString aDocumentsDirURL
= xdg_user_dir_lookup("DOCUMENTS");
400 osl::Directory
aDocumentsDir( aDocumentsDirURL
);
402 if( osl::FileBase::E_None
== aDocumentsDir
.open() )
407 case SETTING_USER_GIVENNAME
:
409 rtl::OUString
aCompleteName( rtl::OStringToOUString(
410 g_get_real_name(), osl_getThreadTextEncoding() ) );
411 if( !aCompleteName
.equalsAscii( "Unknown" ) )
416 case SETTING_USER_SURNAME
:
418 rtl::OUString
aCompleteName( rtl::OStringToOUString(
419 g_get_real_name(), osl_getThreadTextEncoding() ) );
420 if( !aCompleteName
.equalsAscii( "Unknown" ) )
422 if( aCompleteName
.trim().indexOf(rtl::OUString::createFromAscii(" "), 0) != -1 )
428 #ifdef ENABLE_LOCKDOWN
429 case SETTING_AUTO_SAVE
:
431 GConfClient
* aClient
= GconfBackend::getGconfClient();
432 GConfValue
* aGconfValue
= gconf_client_get( aClient
, GCONF_AUTO_SAVE_KEY
, NULL
);
434 if( ( aGconfValue
!= NULL
) )
436 bool bOk
= gconf_value_get_bool( aGconfValue
);
437 gconf_value_free( aGconfValue
);
438 if (bOk
) return sal_True
;
442 #endif // ENABLE_LOCKDOWN
445 fprintf( stderr
, "Unhandled setting to check dependency.\n" );
452 //------------------------------------------------------------------------------
454 void SAL_CALL
GconfLayer::readData( const uno::Reference
<backend::XLayerHandler
>& xHandler
)
455 throw ( backend::MalformedDataException
, lang::NullPointerException
,
456 lang::WrappedTargetException
, uno::RuntimeException
)
458 if( ! m_xLayerContentDescriber
.is() )
460 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
461 "Could not create com.sun.star.configuration.backend.LayerContentDescriber Service"
462 ) ), static_cast < backend::XLayer
* > (this) );
465 uno::Sequence
<backend::PropertyInfo
> aPropInfoList( m_nConfigurationValues
);
466 sal_Int32 nProperties
= 0;
468 GConfClient
* aClient
= GconfBackend::getGconfClient();
469 GConfValue
* aGconfValue
;
472 while( m_pPreloadValuesList
[i
] != NULL
)
473 gconf_client_preload( aClient
, m_pPreloadValuesList
[i
++], GCONF_CLIENT_PRELOAD_ONELEVEL
, NULL
);
475 for( i
= 0; i
< m_nConfigurationValues
; i
++ )
477 if( ( m_pConfigurationValuesList
[i
].nDependsOn
!= SETTINGS_LAST
) && !isDependencySatisfied( m_pConfigurationValuesList
[i
] ) )
480 aGconfValue
= gconf_client_get( aClient
, m_pConfigurationValuesList
[i
].GconfItem
, NULL
);
482 if( aGconfValue
!= NULL
)
484 aPropInfoList
[nProperties
].Name
= rtl::OUString::createFromAscii( m_pConfigurationValuesList
[i
].OOoConfItem
);
485 aPropInfoList
[nProperties
].Type
= rtl::OUString::createFromAscii( m_pConfigurationValuesList
[i
].OOoConfValueType
);
486 aPropInfoList
[nProperties
].Protected
= m_pConfigurationValuesList
[i
].bLocked
;
488 if( m_pConfigurationValuesList
[i
].bNeedsTranslation
)
489 aPropInfoList
[nProperties
].Value
= translateToOOo( m_pConfigurationValuesList
[i
], aGconfValue
);
491 aPropInfoList
[nProperties
].Value
= makeAnyOfGconfValue( aGconfValue
);
493 gconf_value_free( aGconfValue
);
499 if( nProperties
> 0 )
501 aPropInfoList
.realloc( nProperties
);
502 m_xLayerContentDescriber
->describeLayer( xHandler
, aPropInfoList
);
506 //------------------------------------------------------------------------------
508 rtl::OUString SAL_CALL
GconfLayer::getTimestamp( void )
509 throw (uno::RuntimeException
)
511 // Return a hash of the values as timestamp to avoid regenerating
512 // the binary cache on each office launch.
513 rtl::OStringBuffer aTimeStamp
;
515 // Make sure the timestamp differs from beta
516 sal_Int32 nHashCode
= 0;
518 GConfClient
* aClient
= GconfBackend::getGconfClient();
519 GConfValue
* aGconfValue
;
522 while( m_pPreloadValuesList
[i
] != NULL
)
523 gconf_client_preload( aClient
, m_pPreloadValuesList
[i
++], GCONF_CLIENT_PRELOAD_ONELEVEL
, NULL
);
525 for( i
= 0; i
< m_nConfigurationValues
; i
++ )
527 aGconfValue
= gconf_client_get( aClient
, m_pConfigurationValuesList
[i
].GconfItem
, NULL
);
529 if( aGconfValue
!= NULL
)
531 switch( aGconfValue
->type
)
533 case GCONF_VALUE_BOOL
:
534 nHashCode
^= (sal_Int32
) !gconf_value_get_bool( aGconfValue
);
537 case GCONF_VALUE_INT
:
538 nHashCode
^= (sal_Int32
) gconf_value_get_int( aGconfValue
);
541 case GCONF_VALUE_STRING
:
542 nHashCode
^= (sal_Int32
) g_str_hash( gconf_value_get_string( aGconfValue
) );
545 case GCONF_VALUE_LIST
:
546 if( GCONF_VALUE_STRING
== gconf_value_get_list_type( aGconfValue
) )
548 GSList
*list
= gconf_value_get_list( aGconfValue
);
549 for(; list
; list
= g_slist_next(list
))
550 nHashCode
^= (sal_Int32
) g_str_hash( gconf_value_get_string((GConfValue
*) list
->data
) );
555 fprintf( stderr
, "getTimestamp: Type not handled.\n" );
558 nHashCode
= (nHashCode
<< 5) - nHashCode
;
559 gconf_value_free( aGconfValue
);
563 return rtl::OUString::valueOf( nHashCode
);