Update ooo320-m1
[ooovba.git] / shell / source / backends / gconfbe / gconflayer.cxx
blobf6ad4fe776de16e28e7cd86da4dd1cd218428272
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gconflayer.cxx,v $
10 * $Revision: 1.15 $
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>
39 #endif
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>
47 #include <string.h>
49 using namespace rtl;
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 ) );
72 else
74 OSL_TRACE( "Could not retrieve ServiceManager" );
78 //------------------------------------------------------------------------------
80 static OUString xdg_user_dir_lookup (const char *type)
82 char *config_home;
83 char *p;
84 int relative;
85 bool bError = false;
87 osl::Security aSecurity;
88 oslFileHandle handle;
89 OUString aHomeDirURL;
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" );
106 else
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')
120 seq[len-1] = 0;
122 p = (char *)seq.getArray();
124 while (*p == ' ' || *p == '\t')
125 p++;
127 if (strncmp (p, "XDG_", 4) != 0)
128 continue;
129 p += 4;
130 if (strncmp (p, type, strlen (type)) != 0)
131 continue;
132 p += strlen (type);
133 if (strncmp (p, "_DIR", 4) != 0)
134 continue;
135 p += 4;
137 while (*p == ' ' || *p == '\t')
138 p++;
140 if (*p != '=')
141 continue;
142 p++;
144 while (*p == ' ' || *p == '\t')
145 p++;
147 if (*p != '"')
148 continue;
149 p++;
151 relative = 0;
152 if (strncmp (p, "$HOME/", 6) == 0)
154 p += 6;
155 relative = 1;
157 else if (*p != '/')
158 continue;
160 if (relative)
162 aUserDirBuf = OUStringBuffer(aHomeDirURL);
163 aUserDirBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/" ) );
165 else
167 aUserDirBuf = OUStringBuffer();
170 while (*p && *p != '"')
172 if ((*p == '\\') && (*(p+1) != 0))
173 p++;
174 aUserDirBuf.append((sal_Unicode)*p++);
177 osl_closeFile(handle);
179 else
180 bError = true;
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();
197 else
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 ) );
221 default:
222 fprintf( stderr, "makeAnyOfGconfValue: Type not handled.\n" );
223 break;
226 return uno::Any();
229 //------------------------------------------------------------------------------
231 static void splitFontName( GConfValue *aGconfValue, rtl::OUString &rName, sal_Int16 &rHeight)
233 rtl::OString aFont( gconf_value_get_string( aGconfValue ) );
234 aFont.trim();
235 sal_Int32 nIdx = aFont.lastIndexOf( ' ' );
236 if (nIdx < 1) { // urk
237 rHeight = 12;
238 nIdx = aFont.getLength();
239 } else {
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 );
265 break;
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));
276 aBuffer.append(";");
278 // Remove trailing ";"
279 aBuffer.setLength(aBuffer.getLength()-1);
280 return uno::makeAny(rtl::OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8));
282 else
283 g_warning( "unexpected type for ignore_hosts" );
285 break;
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 );
306 break;
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:
358 rtl::OUString aName;
359 sal_Int16 nHeight;
361 splitFontName (aGconfValue, aName, nHeight);
362 if (aValue.nSettingId == SETTING_SOURCEVIEWFONT_NAME)
363 return uno::makeAny( aName );
364 else
365 return uno::makeAny( nHeight );
369 default:
370 fprintf( stderr, "Unhandled setting to translate.\n" );
371 break;
374 return uno::Any();
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;
395 break;
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() )
403 return sal_True;
405 break;
407 case SETTING_USER_GIVENNAME:
409 rtl::OUString aCompleteName( rtl::OStringToOUString(
410 g_get_real_name(), osl_getThreadTextEncoding() ) );
411 if( !aCompleteName.equalsAscii( "Unknown" ) )
412 return sal_True;
414 break;
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 )
423 return sal_True;
426 break;
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;
441 break;
442 #endif // ENABLE_LOCKDOWN
444 default:
445 fprintf( stderr, "Unhandled setting to check dependency.\n" );
446 break;
449 return sal_False;
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;
470 int i = 0;
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] ) )
478 continue;
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 );
490 else
491 aPropInfoList[nProperties].Value = makeAnyOfGconfValue( aGconfValue );
493 gconf_value_free( aGconfValue );
495 nProperties++;
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;
520 int i = 0;
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 );
535 break;
537 case GCONF_VALUE_INT:
538 nHashCode ^= (sal_Int32) gconf_value_get_int( aGconfValue );
539 break;
541 case GCONF_VALUE_STRING:
542 nHashCode ^= (sal_Int32) g_str_hash( gconf_value_get_string( aGconfValue ) );
543 break;
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) );
551 break;
554 default:
555 fprintf( stderr, "getTimestamp: Type not handled.\n" );
556 break;
558 nHashCode = (nHashCode << 5) - nHashCode;
559 gconf_value_free( aGconfValue );
563 return rtl::OUString::valueOf( nHashCode );