Fix string errors reported by Christian Kirbach
[nautilus-actions.git] / src / io-gconf / nagp-reader.c
blob467ffc0263919e10a9ea2011da9d300240368662
1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
9 * This Program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This Program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this Library; see the file COPYING. If not,
21 * write to the Free Software Foundation, Inc., 59 Temple Place,
22 * Suite 330, Boston, MA 02111-1307, USA.
24 * Authors:
25 * Frederic Ruaudel <grumz@grumz.net>
26 * Rodrigo Moya <rodrigo@gnome-db.org>
27 * Pierre Wieser <pwieser@trychlos.org>
28 * ... and many others (see AUTHORS)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <string.h>
37 #include <api/na-data-def.h>
38 #include <api/na-data-types.h>
39 #include <api/na-ifactory-provider.h>
40 #include <api/na-iio-provider.h>
41 #include <api/na-object-api.h>
42 #include <api/na-core-utils.h>
43 #include <api/na-gconf-utils.h>
45 #include "nagp-gconf-provider.h"
46 #include "nagp-keys.h"
47 #include "nagp-reader.h"
49 typedef struct {
50 gchar *path;
51 GSList *entries;
52 NAObjectItem *parent;
54 ReaderData;
56 static NAObjectItem *read_item( NagpGConfProvider *provider, const gchar *path, GSList **messages );
58 static void read_start_profile_attach_profile( const NAIFactoryProvider *provider, NAObjectProfile *profile, ReaderData *data, GSList **messages );
60 static gboolean read_done_item_is_writable( const NAIFactoryProvider *provider, NAObjectItem *item, ReaderData *data, GSList **messages );
61 static void read_done_action_read_profiles( const NAIFactoryProvider *provider, NAObjectAction *action, ReaderData *data, GSList **messages );
62 static void read_done_action_load_profile( const NAIFactoryProvider *provider, ReaderData *data, const gchar *path, GSList **messages );
64 static NADataBoxed *get_boxed_from_path( const NagpGConfProvider *provider, const gchar *path, ReaderData *reader_data, const NADataDef *def );
65 static gboolean is_key_writable( NagpGConfProvider *gconf, const gchar *key );
68 * nagp_iio_provider_read_items:
70 * Note that whatever be the version of the read action, it will be
71 * stored as a #NAObjectAction and its set of #NAObjectProfile of the same,
72 * latest, version of these classes.
74 GList *
75 nagp_iio_provider_read_items( const NAIIOProvider *provider, GSList **messages )
77 static const gchar *thisfn = "nagp_gconf_provider_iio_provider_read_items";
78 NagpGConfProvider *self;
79 GList *items_list = NULL;
80 GSList *listpath, *ip;
81 NAObjectItem *item;
83 g_debug( "%s: provider=%p, messages=%p", thisfn, ( void * ) provider, ( void * ) messages );
85 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), NULL );
86 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), NULL );
87 self = NAGP_GCONF_PROVIDER( provider );
89 if( !self->private->dispose_has_run ){
91 listpath = na_gconf_utils_get_subdirs( self->private->gconf, NAGP_CONFIGURATIONS_PATH );
93 for( ip = listpath ; ip ; ip = ip->next ){
95 item = read_item( self, ( const gchar * ) ip->data, messages );
96 if( item ){
97 items_list = g_list_prepend( items_list, item );
101 na_gconf_utils_free_subdirs( listpath );
104 g_debug( "%s: count=%d", thisfn, g_list_length( items_list ));
105 return( items_list );
109 * path is here the full path to an item
111 static NAObjectItem *
112 read_item( NagpGConfProvider *provider, const gchar *path, GSList **messages )
114 static const gchar *thisfn = "nagp_gconf_provider_read_item";
115 NAObjectItem *item;
116 gchar *full_path;
117 gchar *type;
118 gchar *id;
119 ReaderData *data;
121 g_debug( "%s: provider=%p, path=%s", thisfn, ( void * ) provider, path );
122 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), NULL );
123 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), NULL );
124 g_return_val_if_fail( !provider->private->dispose_has_run, NULL );
126 full_path = gconf_concat_dir_and_key( path, NAGP_ENTRY_TYPE );
127 type = na_gconf_utils_read_string( provider->private->gconf, full_path, TRUE, NAGP_VALUE_TYPE_ACTION );
128 g_free( full_path );
129 item = NULL;
131 /* a menu may have 'Action' or 'Menu' type ; defaults to Action
133 if( !type || !strlen( type ) || !strcmp( type, NAGP_VALUE_TYPE_ACTION )){
134 item = NA_OBJECT_ITEM( na_object_action_new());
136 } else if( !strcmp( type, NAGP_VALUE_TYPE_MENU )){
137 item = NA_OBJECT_ITEM( na_object_menu_new());
139 } else {
140 g_warning( "%s: unknown type '%s' at %s", thisfn, type, path );
143 g_free( type );
145 if( item ){
146 id = g_path_get_basename( path );
147 na_object_set_id( item, id );
148 g_free( id );
150 data = g_new0( ReaderData, 1 );
151 data->path = ( gchar * ) path;
152 data->entries = na_gconf_utils_get_entries( provider->private->gconf, path );
153 na_gconf_utils_dump_entries( data->entries );
155 na_ifactory_provider_read_item(
156 NA_IFACTORY_PROVIDER( provider ),
157 data,
158 NA_IFACTORY_OBJECT( item ),
159 messages );
161 na_gconf_utils_free_entries( data->entries );
162 g_free( data );
165 return( item );
168 void
169 nagp_reader_read_start( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages )
171 static const gchar *thisfn = "nagp_reader_read_start";
173 g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider ));
174 g_return_if_fail( NAGP_IS_GCONF_PROVIDER( provider ));
175 g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
177 if( !NAGP_GCONF_PROVIDER( provider )->private->dispose_has_run ){
179 g_debug( "%s: provider=%p (%s), reader_data=%p, object=%p (%s), messages=%p",
180 thisfn,
181 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
182 ( void * ) reader_data,
183 ( void * ) object, G_OBJECT_TYPE_NAME( object ),
184 ( void * ) messages );
186 if( NA_IS_OBJECT_PROFILE( object )){
187 read_start_profile_attach_profile( provider, NA_OBJECT_PROFILE( object ), ( ReaderData * ) reader_data, messages );
192 static void
193 read_start_profile_attach_profile( const NAIFactoryProvider *provider, NAObjectProfile *profile, ReaderData *data, GSList **messages )
195 na_object_attach_profile( data->parent, profile );
198 NADataBoxed *
199 nagp_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages )
201 static const gchar *thisfn = "nagp_reader_read_data";
202 NADataBoxed *boxed;
204 g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( provider ), NULL );
205 g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
207 /*g_debug( "%s: reader_data=%p, object=%p (%s), data=%s",
208 thisfn,
209 ( void * ) reader_data,
210 ( void * ) object, G_OBJECT_TYPE_NAME( object ),
211 def->name );*/
213 if( !def->gconf_entry || !strlen( def->gconf_entry )){
214 g_warning( "%s: GConf entry is not set for NADataDef %s", thisfn, def->name );
215 return( NULL );
218 boxed = get_boxed_from_path(
219 NAGP_GCONF_PROVIDER( provider ), (( ReaderData * ) reader_data )->path, reader_data, def );
221 return( boxed );
224 void
225 nagp_reader_read_done( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages )
227 static const gchar *thisfn = "nagp_reader_read_done";
228 gboolean writable;
230 g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider ));
231 g_return_if_fail( NAGP_IS_GCONF_PROVIDER( provider ));
232 g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
234 if( !NAGP_GCONF_PROVIDER( provider )->private->dispose_has_run ){
236 g_debug( "%s: provider=%p (%s), reader_data=%p, object=%p (%s), messages=%p",
237 thisfn,
238 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
239 ( void * ) reader_data,
240 ( void * ) object, G_OBJECT_TYPE_NAME( object ),
241 ( void * ) messages );
243 if( NA_IS_OBJECT_ITEM( object )){
244 writable = read_done_item_is_writable( provider, NA_OBJECT_ITEM( object ), ( ReaderData * ) reader_data, messages );
245 na_object_set_readonly( object, !writable );
248 if( NA_IS_OBJECT_ACTION( object )){
249 read_done_action_read_profiles( provider, NA_OBJECT_ACTION( object ), ( ReaderData * ) reader_data, messages );
252 g_debug( "%s: quitting for %s at %p", thisfn, G_OBJECT_TYPE_NAME( object ), ( void * ) object );
256 static gboolean
257 read_done_item_is_writable( const NAIFactoryProvider *provider, NAObjectItem *item, ReaderData *data, GSList **messages )
259 GSList *ie;
260 gboolean writable;
261 GConfEntry *gconf_entry;
262 const gchar *key;
264 /* check for writability of this item
265 * item is writable if and only if all entries are themselves writable
267 writable = TRUE;
268 for( ie = data->entries ; ie && writable ; ie = ie->next ){
269 gconf_entry = ( GConfEntry * ) ie->data;
270 key = gconf_entry_get_key( gconf_entry );
271 writable = is_key_writable( NAGP_GCONF_PROVIDER( provider ), key );
274 g_debug( "nagp_reader_read_done_item: writable=%s", writable ? "True":"False" );
275 return( writable );
278 static void
279 read_done_action_read_profiles( const NAIFactoryProvider *provider, NAObjectAction *action, ReaderData *data, GSList **messages )
281 GSList *order;
282 GSList *list_profiles;
283 GSList *ip;
284 gchar *profile_id;
285 gchar *profile_path;
286 NAObjectId *found;
288 data->parent = NA_OBJECT_ITEM( action );
289 order = na_object_get_items_slist( action );
290 list_profiles = na_gconf_utils_get_subdirs( NAGP_GCONF_PROVIDER( provider )->private->gconf, data->path );
292 /* read profiles in the specified order
293 * as a protection against bugs in NACT, we check that profile has not
294 * already been loaded
296 for( ip = order ; ip ; ip = ip->next ){
297 profile_id = ( gchar * ) ip->data;
298 found = na_object_get_item( action, profile_id );
299 if( !found ){
300 g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id );
301 profile_path = gconf_concat_dir_and_key( data->path, profile_id );
302 read_done_action_load_profile( provider, data, profile_path, messages );
303 g_free( profile_path );
307 /* append other profiles
308 * this is mandatory for pre-2.29 actions which introduced order of profiles
310 for( ip = list_profiles ; ip ; ip = ip->next ){
311 profile_id = g_path_get_basename(( const gchar * ) ip->data );
312 found = na_object_get_item( action, profile_id );
313 if( !found ){
314 g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id );
315 read_done_action_load_profile( provider, data, ( const gchar * ) ip->data, messages );
317 g_free( profile_id );
321 static void
322 read_done_action_load_profile( const NAIFactoryProvider *provider, ReaderData *data, const gchar *path, GSList **messages )
324 gchar *id;
325 ReaderData *profile_data;
327 NAObjectProfile *profile = na_object_profile_new();
329 id = g_path_get_basename( path );
330 na_object_set_id( profile, id );
331 g_free( id );
333 profile_data = g_new0( ReaderData, 1 );
334 profile_data->parent = data->parent;
335 profile_data->path = ( gchar * ) path;
336 profile_data->entries = na_gconf_utils_get_entries( NAGP_GCONF_PROVIDER( provider )->private->gconf, path );
338 na_ifactory_provider_read_item(
339 NA_IFACTORY_PROVIDER( provider ),
340 profile_data,
341 NA_IFACTORY_OBJECT( profile ),
342 messages );
344 na_gconf_utils_free_entries( profile_data->entries );
345 g_free( profile_data );
348 static NADataBoxed *
349 get_boxed_from_path( const NagpGConfProvider *provider, const gchar *path, ReaderData *reader_data, const NADataDef *def )
351 static const gchar *thisfn = "nagp_reader_get_boxed_from_path";
352 NADataBoxed *boxed;
353 gboolean have_entry;
354 gchar *str_value;
355 gboolean bool_value;
356 GSList *slist_value;
357 gint int_value;
359 boxed = NULL;
360 have_entry = na_gconf_utils_has_entry( reader_data->entries, def->gconf_entry );
361 g_debug( "%s: entry=%s, have_entry=%s", thisfn, def->gconf_entry, have_entry ? "True":"False" );
363 if( have_entry ){
364 boxed = na_data_boxed_new( def );
365 gchar *entry_path = gconf_concat_dir_and_key( path, def->gconf_entry );
367 switch( def->type ){
369 case NAFD_TYPE_STRING:
370 case NAFD_TYPE_LOCALE_STRING:
371 str_value = na_gconf_utils_read_string( provider->private->gconf, entry_path, TRUE, NULL );
372 g_debug( "%s: entry=%s, value=%s", thisfn, def->gconf_entry, str_value );
373 na_data_boxed_set_from_string( boxed, str_value );
374 g_free( str_value );
375 break;
377 case NAFD_TYPE_BOOLEAN:
378 bool_value = na_gconf_utils_read_bool( provider->private->gconf, entry_path, TRUE, FALSE );
379 na_data_boxed_set_from_void( boxed, GUINT_TO_POINTER( bool_value ));
380 break;
382 case NAFD_TYPE_STRING_LIST:
383 slist_value = na_gconf_utils_read_string_list( provider->private->gconf, entry_path );
384 na_data_boxed_set_from_void( boxed, slist_value );
385 na_core_utils_slist_free( slist_value );
386 break;
388 case NAFD_TYPE_UINT:
389 int_value = na_gconf_utils_read_int( provider->private->gconf, entry_path, TRUE, 0 );
390 na_data_boxed_set_from_void( boxed, GUINT_TO_POINTER( int_value ));
391 break;
393 default:
394 g_warning( "%s: unknown type=%u for %s", thisfn, def->type, def->name );
395 g_free( boxed );
396 boxed = NULL;
399 g_free( entry_path );
402 return( boxed );
406 * key must be an existing entry (not a dir) to get a relevant return
407 * value ; else we get FALSE
409 static gboolean
410 is_key_writable( NagpGConfProvider *gconf, const gchar *key )
412 static const gchar *thisfn = "nagp_read_is_key_writable";
413 GError *error = NULL;
414 gboolean is_writable;
416 is_writable = gconf_client_key_is_writable( gconf->private->gconf, key, &error );
417 if( error ){
418 g_warning( "%s: gconf_client_key_is_writable: %s", thisfn, error->message );
419 g_error_free( error );
420 error = NULL;
421 is_writable = FALSE;
424 return( is_writable );