Address each occurrence of selected instead of just the first one
[nautilus-actions.git] / src / io-gconf / nagp-writer.c
blobe662f5514155da6f705270f0fccd5919ac546155
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 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-iio-provider.h>
40 #include <api/na-ifactory-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-writer.h"
47 #include "nagp-keys.h"
49 static void write_start_write_type( NagpGConfProvider *provider, NAObjectItem *item );
50 static void write_start_write_version( NagpGConfProvider *provider, NAObjectItem *item );
53 * API function: should only be called through NAIIOProvider interface
55 gboolean
56 nagp_iio_provider_is_willing_to_write( const NAIIOProvider *provider )
58 return( TRUE );
62 * Rationale: gconf reads its storage path from /etc/gconf/2/path ;
63 * there is there a 'xml:readwrite:$(HOME)/.gconf' line, but I do not
64 * known any way to get it programatically, so an admin may have set a
65 * readwrite space elsewhere..
67 * So, we try to write a 'foo' key somewhere: if it is ok, then the
68 * provider is supposed able to write...
70 * API function: should only be called through NAIIOProvider interface
72 gboolean
73 nagp_iio_provider_is_able_to_write( const NAIIOProvider *provider )
75 static const gchar *thisfn = "nagp_iio_provider_is_able_to_write";
76 static const gchar *path = "/apps/nautilus-actions/foo";
77 NagpGConfProvider *self;
78 gboolean able_to = FALSE;
80 /*g_debug( "%s: provider=%p", thisfn, ( void * ) provider );*/
81 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), FALSE );
82 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), FALSE );
84 self = NAGP_GCONF_PROVIDER( provider );
86 if( !self->private->dispose_has_run ){
88 if( !na_gconf_utils_write_string( self->private->gconf, path, "foo", NULL )){
89 able_to = FALSE;
91 } else {
92 gchar *str = na_gconf_utils_read_string( self->private->gconf, path, FALSE, NULL );
93 if( strcmp( str, "foo" )){
94 able_to = FALSE;
96 } else if( !gconf_client_recursive_unset( self->private->gconf, path, 0, NULL )){
97 able_to = FALSE;
99 } else {
100 able_to = TRUE;
103 g_free( str );
107 gconf_client_suggest_sync( self->private->gconf, NULL );
109 g_debug( "%s: provider=%p, able_to=%s", thisfn, ( void * ) provider, able_to ? "True":"False" );
110 return( able_to );
114 * update an existing item or write a new one
115 * in all cases, it is much more easy to delete the existing entries
116 * before trying to write the new ones
118 guint
119 nagp_iio_provider_write_item( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages )
121 static const gchar *thisfn = "nagp_gconf_provider_iio_provider_write_item";
122 NagpGConfProvider *self;
123 guint ret;
125 g_debug( "%s: provider=%p (%s), item=%p (%s), messages=%p",
126 thisfn,
127 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
128 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
129 ( void * ) messages );
131 ret = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
133 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), ret );
134 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), ret );
135 g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), ret );
137 self = NAGP_GCONF_PROVIDER( provider );
139 if( self->private->dispose_has_run ){
140 return( NA_IIO_PROVIDER_CODE_NOT_WILLING_TO_RUN );
143 ret = nagp_iio_provider_delete_item( provider, item, messages );
145 if( ret == NA_IIO_PROVIDER_CODE_OK ){
146 na_ifactory_provider_write_item( NA_IFACTORY_PROVIDER( provider ), NULL, NA_IFACTORY_OBJECT( item ), messages );
149 gconf_client_suggest_sync( self->private->gconf, NULL );
151 return( ret );
155 * also delete the schema which may be directly attached to this action
156 * cf. http://bugzilla.gnome.org/show_bug.cgi?id=325585
158 guint
159 nagp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages )
161 static const gchar *thisfn = "nagp_gconf_provider_iio_provider_delete_item";
162 NagpGConfProvider *self;
163 guint ret;
164 gchar *uuid, *path;
165 GError *error = NULL;
167 g_debug( "%s: provider=%p (%s), item=%p (%s), messages=%p",
168 thisfn,
169 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
170 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
171 ( void * ) messages );
173 ret = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
175 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), ret );
176 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), ret );
177 g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), ret );
179 self = NAGP_GCONF_PROVIDER( provider );
181 if( self->private->dispose_has_run ){
182 return( NA_IIO_PROVIDER_CODE_NOT_WILLING_TO_RUN );
185 ret = NA_IIO_PROVIDER_CODE_OK;
186 uuid = na_object_get_id( NA_OBJECT( item ));
188 /* GCONF_UNSET_INCLUDING_SCHEMA_NAMES seems mean: including the name
189 * of the schemas which is embedded in the GConfEntry - this doesn't
190 * mean including the schemas themselves
192 if( ret == NA_IIO_PROVIDER_CODE_OK ){
193 path = gconf_concat_dir_and_key( NAGP_CONFIGURATIONS_PATH, uuid );
194 gconf_client_recursive_unset( self->private->gconf, path, GCONF_UNSET_INCLUDING_SCHEMA_NAMES, &error );
195 if( error ){
196 g_warning( "%s: path=%s, error=%s", thisfn, path, error->message );
197 *messages = g_slist_append( *messages, g_strdup( error->message ));
198 g_error_free( error );
199 error = NULL;
200 ret = NA_IIO_PROVIDER_CODE_DELETE_CONFIG_ERROR;
202 gconf_client_suggest_sync( self->private->gconf, NULL );
203 g_free( path );
206 if( ret == NA_IIO_PROVIDER_CODE_OK ){
207 path = gconf_concat_dir_and_key( NAGP_SCHEMAS_PATH, uuid );
208 gconf_client_recursive_unset( self->private->gconf, path, 0, &error );
209 if( error ){
210 g_warning( "%s: path=%s, error=%s", thisfn, path, error->message );
211 *messages = g_slist_append( *messages, g_strdup( error->message ));
212 g_error_free( error );
213 error = NULL;
214 ret = NA_IIO_PROVIDER_CODE_DELETE_SCHEMAS_ERROR;
216 g_free( path );
217 gconf_client_suggest_sync( self->private->gconf, NULL );
220 g_free( uuid );
222 return( ret );
225 guint
226 nagp_writer_write_start( const NAIFactoryProvider *writer, void *writer_data,
227 const NAIFactoryObject *object, GSList **messages )
229 if( NA_IS_OBJECT_ITEM( object )){
230 write_start_write_type( NAGP_GCONF_PROVIDER( writer ), NA_OBJECT_ITEM( object ));
231 write_start_write_version( NAGP_GCONF_PROVIDER( writer ), NA_OBJECT_ITEM( object ));
234 return( NA_IIO_PROVIDER_CODE_OK );
237 static void
238 write_start_write_type( NagpGConfProvider *provider, NAObjectItem *item )
240 gchar *id, *path;
242 id = na_object_get_id( item );
243 path = g_strdup_printf( "%s/%s/%s", NAGP_CONFIGURATIONS_PATH, id, NAGP_ENTRY_TYPE );
245 na_gconf_utils_write_string(
246 provider->private->gconf,
247 path,
248 NA_IS_OBJECT_ACTION( item ) ? NAGP_VALUE_TYPE_ACTION : NAGP_VALUE_TYPE_MENU,
249 NULL );
251 g_free( path );
252 g_free( id );
255 static void
256 write_start_write_version( NagpGConfProvider *provider, NAObjectItem *item )
258 gchar *id, *path;
259 guint iversion;
261 id = na_object_get_id( item );
262 path = g_strdup_printf( "%s/%s/%s", NAGP_CONFIGURATIONS_PATH, id, NAGP_ENTRY_IVERSION );
264 iversion = na_object_get_iversion( item );
265 na_gconf_utils_write_int( provider->private->gconf, path, iversion, NULL );
267 g_free( path );
268 g_free( id );
271 guint
272 nagp_writer_write_data( const NAIFactoryProvider *provider, void *writer_data,
273 const NAIFactoryObject *object, const NADataBoxed *boxed,
274 GSList **messages )
276 static const gchar *thisfn = "nagp_writer_write_data";
277 guint code;
278 NADataDef *def;
279 gchar *this_id;
280 gchar *this_path, *path;
281 gchar *msg;
282 gchar *str_value;
283 gboolean bool_value;
284 GSList *slist_value;
285 guint uint_value;
286 GConfClient *gconf;
288 /*g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));*/
290 msg = NULL;
291 code = NA_IIO_PROVIDER_CODE_OK;
292 def = na_data_boxed_get_data_def( boxed );
294 if( !na_data_boxed_is_default( boxed ) || def->write_if_default ){
296 if( NA_IS_OBJECT_PROFILE( object )){
297 NAObjectItem *parent = NA_OBJECT_ITEM( na_object_get_parent( object ));
298 gchar *parent_id = na_object_get_id( parent );
299 gchar *id = na_object_get_id( object );
300 this_id = g_strdup_printf( "%s/%s", parent_id, id );
301 g_free( id );
302 g_free( parent_id );
304 } else {
305 this_id = na_object_get_id( object );
308 this_path = gconf_concat_dir_and_key( NAGP_CONFIGURATIONS_PATH, this_id );
309 path = gconf_concat_dir_and_key( this_path, def->gconf_entry );
311 gconf = NAGP_GCONF_PROVIDER( provider )->private->gconf;
313 switch( def->type ){
315 case NAFD_TYPE_STRING:
316 str_value = na_data_boxed_get_as_string( boxed );
317 na_gconf_utils_write_string( gconf, path, str_value, &msg );
318 if( msg ){
319 *messages = g_slist_append( *messages, msg );
320 code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
322 g_free( str_value );
323 break;
325 case NAFD_TYPE_LOCALE_STRING:
326 str_value = na_data_boxed_get_as_string( boxed );
327 na_gconf_utils_write_string( gconf, path, str_value, &msg );
328 if( msg ){
329 *messages = g_slist_append( *messages, msg );
330 code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
332 g_free( str_value );
333 break;
335 case NAFD_TYPE_BOOLEAN:
336 bool_value = GPOINTER_TO_UINT( na_data_boxed_get_as_void( boxed ));
337 na_gconf_utils_write_bool( gconf, path, bool_value, &msg );
338 if( msg ){
339 *messages = g_slist_append( *messages, msg );
340 code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
342 break;
344 case NAFD_TYPE_STRING_LIST:
345 slist_value = ( GSList * ) na_data_boxed_get_as_void( boxed );
346 na_gconf_utils_write_string_list( gconf, path, slist_value, &msg );
347 if( msg ){
348 *messages = g_slist_append( *messages, msg );
349 code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
351 na_core_utils_slist_free( slist_value );
352 break;
354 case NAFD_TYPE_UINT:
355 uint_value = GPOINTER_TO_UINT( na_data_boxed_get_as_void( boxed ));
356 na_gconf_utils_write_int( gconf, path, uint_value, &msg );
357 if( msg ){
358 *messages = g_slist_append( *messages, msg );
359 code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
361 break;
363 default:
364 g_warning( "%s: unknown type=%u for %s", thisfn, def->type, def->name );
365 code = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
368 /*g_debug( "%s: gconf=%p, code=%u, path=%s", thisfn, ( void * ) gconf, code, path );*/
370 g_free( msg );
371 g_free( path );
372 g_free( this_path );
373 g_free( this_id );
376 return( code );
379 guint
380 nagp_writer_write_done( const NAIFactoryProvider *writer, void *writer_data,
381 const NAIFactoryObject *object,
382 GSList **messages )
384 return( NA_IIO_PROVIDER_CODE_OK );